Codevs_1082_线段树练习3
http://codevs.cn/problem/1082/
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 const int maxn=200005; 6 typedef long long ll; 7 int n,q; 8 int w[maxn]; 9 struct node { int l,r; ll x,d; }a[3*maxn]; 10 11 void build_tree(int l,int r,int k) 12 { 13 a[k].l=l; a[k].r=r; a[k].d=0; 14 if(l==r) { a[k].x=w[l]; return; } 15 int mid=l+(r-l)/2; 16 build_tree(l,mid,2*k); 17 build_tree(mid+1,r,2*k+1); 18 a[k].x=a[2*k].x+a[2*k+1].x; 19 } 20 21 void update(int l,int r,int k,int x) 22 { 23 if(a[k].l==l&&a[k].r==r) 24 { 25 a[k].x+=(r-l+1)*x; 26 a[k].d+=x; 27 return; 28 } 29 30 if(a[k].d) 31 { 32 a[2*k].x+=(a[2*k].r-a[2*k].l+1)*a[k].d; 33 a[2*k+1].x+=(a[2*k+1].r-a[2*k+1].l+1)*a[k].d; 34 a[2*k].d+=a[k].d; 35 a[2*k+1].d+=a[k].d; 36 a[k].d=0; 37 } 38 int mid=a[k].l+(a[k].r-a[k].l)/2; 39 if(r<=mid) update(l,r,2*k,x); 40 else if(l>mid) update(l,r,2*k+1,x); 41 else { update(l,mid,2*k,x); update(mid+1,r,2*k+1,x); } 42 a[k].x=a[2*k].x+a[2*k+1].x; 43 } 44 45 ll search(int l,int r,int k) 46 { 47 if(a[k].l==l&&a[k].r==r) return a[k].x; 48 if(a[k].d) 49 { 50 a[2*k].x+=(a[2*k].r-a[2*k].l+1)*a[k].d; 51 a[2*k+1].x+=(a[2*k+1].r-a[2*k+1].l+1)*a[k].d; 52 a[2*k].d+=a[k].d; 53 a[2*k+1].d+=a[k].d; 54 a[k].d=0; 55 } 56 int mid=a[k].l+(a[k].r-a[k].l)/2; 57 if(r<=mid) return search(l,r,2*k); 58 else if(l>mid) return search(l,r,2*k+1); 59 else return search(l,mid,2*k)+search(mid+1,r,2*k+1); 60 } 61 62 int main() 63 { 64 scanf("%d",&n); 65 for(int i=1;i<=n;i++) scanf("%d",&w[i]); 66 67 build_tree(1,n,1); 68 scanf("%d",&q); 69 for(int i=1;i<=q;i++) 70 { 71 int qry,l,r,x; 72 scanf("%d%d%d",&qry,&l,&r); 73 switch(qry) 74 { 75 case 1: 76 scanf("%d",&x); 77 update(l,r,1,x); 78 break; 79 case 2: 80 printf("%lld ",search(l,r,1)); 81 break; 82 } 83 } 84 return 0; 85 }