線段樹 - HDU 4027 - Can you answer these queries?
阿新 • • 發佈:2020-10-29
-
題目要求維護區間開方和,但由於
\[tree[root] \neq sqrt(tree[leftroot] +tree[rightroot]) \]因此每一個更新操作都需要深入到葉子結點
-
由於這麼做複雜度太高,甚至弱於普通陣列,因此考慮優化
\[tree[root] = right - left+1 表明[left,right]區間全為1,再開方更新仍為1 \]因此再update操作時判斷一下,進行剪枝
-
本題坑點是輸入資料不保證\(l < r\),需要特判替換,否則TLE
-
注意開long long
#include <cstdio> #include <cmath> #include <cstdlib> using namespace std; #define N 100000+5 typedef long long ll; ll arr[N]; ll tree[N<<2]; void build_tree(int left,int right,int root){ if(left == right){ tree[root] = arr[left]; }else{ int mid = (left+right)>>1; int left_root = root<<1; int right_root = root<<1|1; build_tree(left,mid,left_root); build_tree(mid+1,right,right_root); tree[root] = tree[left_root]+tree[right_root]; } } void update(int left,int right,int root,int update_left,int update_right){ if(update_left > right || update_right < left || tree[root] == right-left+1){ return; }else{ if(left == right){ tree[root] = (int)sqrt(tree[root]); }else{ int mid = (left+right)>>1; int left_root = root<<1; int right_root = root<<1|1; update(left,mid,left_root,update_left,update_right); update(mid+1,right,right_root,update_left,update_right); tree[root] = tree[left_root] + tree[right_root]; } } } ll query(int left,int right,int root,int query_left,int query_right){ if(query_left <= left && query_right >= right){ return tree[root]; }else{ int mid = (left+right)>>1; int left_root = root<<1; int right_root = root<<1|1; ll ans = 0; if(query_left <= mid){ ans += query(left,mid,left_root,query_left,query_right); } if(query_right > mid){ ans += query(mid+1,right,right_root,query_left,query_right); } return ans; } } int main(){ int n; int g = 1; while(scanf("%d",&n) != EOF){ printf("Case #%d:\n",g++); for(int i = 1; i <= n; i++){ scanf("%lld",&arr[i]); } build_tree(1,n,1); int q; int a,b,c; scanf("%d",&q); while(q--){ scanf("%d%d%d",&a,&b,&c); if(b > c){ int temp = c; c = b; b = temp; } if(a == 0){ update(1,n,1,b,c); }else{ printf("%lld\n",query(1,n,1,b,c)); } } putchar('\n'); } system("pause"); return 0; }