点击打开链接poj 3468
思路:线段树成段更新
分析:
1 最基础的线段树的成段更新的题目,我们只要建好线段树然后进行更新即可
2 注意由于输入的数最大为10^9,因此我们应该使用long long,区间的和已经区间的延时标记都要为long long
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long int64; const int MAXN = 100010; struct Node{ int left; int right; int64 mark; int64 sum; }; Node node[4*MAXN]; int64 num[MAXN]; int N , Q; //向上更新 void push_up(int pos){ node[pos].sum = node[pos<<1].sum + node[(pos<<1)+1].sum; } //向下更新 void push_down(int pos){ if(node[pos].mark){ node[pos<<1].mark += node[pos].mark; node[(pos<<1)+1].mark += node[pos].mark; node[pos<<1].sum += node[pos].mark*(node[pos<<1].right-node[pos<<1].left+1); node[(pos<<1)+1].sum += node[pos].mark*(node[(pos<<1)+1].right-node[(pos<<1)+1].left+1); node[pos].mark = 0; } } //建立线段树 void buildTree(int left , int right , int pos){ node[pos].left = left; node[pos].right = right; node[pos].mark = 0; if(left == right){ node[pos].sum = num[left]; node[pos].mark = num[left]; return; } int mid = (left+right)>>1; buildTree(left , mid , pos<<1); buildTree(mid+1 , right , (pos<<1)+1); push_up(pos);//向上更新 } //成段更新 void update(int left , int right , int value , int pos){ if(left <= node[pos].left && right >= node[pos].right){ node[pos].mark += value; node[pos].sum += value*(node[pos].right-node[pos].left+1); return ; } push_down(pos); int mid = (node[pos].left+node[pos].right)>>1; if(right <= mid) update(left , right , value , pos<<1); else if(left > mid) update(left , right , value , (pos<<1)+1); else{ update(left , mid , value , pos<<1); update(mid+1 , right , value , (pos<<1)+1); } push_up(pos); } int64 query(int left , int right , int pos){ if(node[pos].left == left && node[pos].right == right) return node[pos].sum; int mid = (node[pos].left+node[pos].right)>>1; push_down(pos);//继续向下更新,才能完全更新完毕 if(right <= mid) return query(left , right , pos<<1); else if(left > mid) return query(left , right , (pos<<1)+1); else return query(left , mid , pos<<1) + query(mid+1 , right , (pos<<1)+1); } int main(){ char str[MAXN] , ch; int x , y , d; while(scanf("%d%d" , &N , &Q) != EOF){ for(int i = 1 ; i <= N ; i++) scanf("%lld" , &num[i]); gets(str); buildTree(1 , N , 1); for(int i = 0 ; i < Q ; i++){ gets(str); if(str[0] == 'Q'){ sscanf(str , "%c %d %d" , &ch , &x , &y); printf("%lld\n" , query(x , y , 1)); } else{ sscanf(str , "%c %d %d %d" , &ch , &x , &y , &d); update(x , y , d , 1); } } } return 0; }