题目:http://poj.org/problem?id=3468
题意:在一组数中执行两种操作
"C a b c" means adding c to each of A a, A a+1, ... , A b. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of A a, A a+1, ... , A b.
"C a b c" means adding c to each of A a, A a+1, ... , A b. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of A a, A a+1, ... , A b.
[线段树][延时更新]
注意:区间长度为s[u].r-s[u].l+1,加1容易被忽略;延时更新s[u].add+=ad,因为是延时更新可能之前存的还没有往后加;
提示:本题只适用线段树;树状数组能解决的问题线段树都能解决;但线段树是O(nlogn),而树状数组是O(logn),且树状数组的代码实现更简单;
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cstring> 6 #define L(u) (u<<1) 7 #define R(u) (u<<1|1) 8 using namespace std; 9 int a[400000]; 10 int n,q; 11 struct poin{ 12 int l,r; 13 long long sum; 14 long long add; 15 }s[400000]; 16 void upush(int u) 17 { 18 s[u].sum=s[L(u)].sum+s[R(u)].sum; 19 return ; 20 } 21 void downpush(int u) 22 { 23 s[L(u)].add+=s[u].add; 24 s[R(u)].add+=s[u].add; 25 s[L(u)].sum+=(s[L(u)].r-s[L(u)].l+1)*s[u].add; 26 s[R(u)].sum+=(s[R(u)].r-s[R(u)].l+1)*s[u].add; 27 s[u].add=0; 28 return ; 29 } 30 void adding(int u,int left,int right,int ad) 31 { 32 if(left<=s[u].l&&right>=s[u].r) 33 { 34 s[u].sum+=(s[u].r-s[u].l+1)*ad; 35 s[u].add+=ad; 36 return ; 37 } 38 if(s[u].add)downpush(u); 39 int mid=(s[u].l+s[u].r)>>1; 40 if(right<=mid) 41 adding(L(u),left,right,ad); 42 else if(left>mid) 43 adding(R(u),left,right,ad); 44 else 45 { 46 adding(L(u),left,mid,ad); 47 adding(R(u),mid+1,right,ad); 48 } 49 upush(u); 50 } 51 long long query(int u,int left,int right) 52 { 53 if(left<=s[u].l&&right>=s[u].r) 54 return s[u].sum; 55 if(s[u].add)downpush(u); 56 int mid=(s[u].l+s[u].r)>>1; 57 if(right<=mid)return query(L(u),left,right); 58 else if(left>mid)return query(R(u),left,right); 59 else return (query(L(u),left,mid)+query(R(u),mid+1,right)); 60 upush(u); 61 } 62 void build(int u,int left,int right) 63 { 64 s[u].l=left; 65 s[u].r=right; 66 if(s[u].l==s[u].r) 67 { 68 s[u].sum=a[left]; 69 return ; 70 } 71 int mid=(left+right)>>1; 72 build(L(u),left,mid); 73 build(R(u),mid+1,right); 74 upush(u); 75 76 } 77 int main() 78 { 79 cin>>n>>q; 80 for(int i=1;i<=n;i++) 81 scanf("%d",&a[i]); 82 build(1,1,n); 83 for(int i=1;i<=q;i++) 84 { 85 char w; 86 w=getchar(); 87 while(w!='C'&&w!='Q') 88 w=getchar(); 89 if(w=='C') 90 { 91 int y,o,u; 92 scanf("%d%d%d",&y,&o,&u); 93 adding(1,y,o,u); 94 } 95 if(w=='Q') 96 { 97 int y,o; 98 scanf("%d%d",&y,&o); 99 long long e=query(1,y,o); 100 cout<<e; 101 printf("\n"); 102 } 103 } 104 return 0; 105 }