线段树 区间查询区间修改 poj 3468
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 typedef long long ll; 7 const ll maxn=1e5+10; 8 ll ary[maxn]; 9 struct node 10 { 11 ll l,r,val; 12 ll add; 13 }tree[maxn<<2]; 14 void pushup(ll cur) 15 { 16 tree[cur].val=tree[cur<<1].val+tree[cur<<1|1].val; 17 } 18 void down(ll cur,ll len) 19 { 20 if(tree[cur].add){ 21 tree[cur<<1].val+=(len-(len>>1))*tree[cur].add; 22 tree[cur<<1|1].val+=(len>>1)*tree[cur].add; 23 tree[cur<<1].add+=tree[cur].add; 24 tree[cur<<1|1].add+=tree[cur].add; 25 tree[cur].add=0; 26 } 27 } 28 void build(ll l,ll r,ll cur) 29 { 30 tree[cur].l=l,tree[cur].r=r; 31 tree[cur].val=tree[cur].add=0; 32 if(l==r){ 33 tree[cur].val=ary[l]; 34 return; 35 } 36 ll mid=(l+r)/2; 37 build(l,mid,cur<<1); 38 build(mid+1,r,cur<<1|1); 39 pushup(cur); 40 } 41 ll query(ll l,ll r,ll cur) 42 { 43 ll L=tree[cur].l,R=tree[cur].r; 44 if(l<=L&&r>=R) return tree[cur].val; 45 down(cur,R-L+1); 46 ll mid=(L+R)/2; 47 ll ans=0; 48 if(l<=mid) ans+=query(l,r,cur<<1); 49 if(r>mid) ans+=query(l,r,cur<<1|1); 50 return ans; 51 } 52 void update(ll l,ll r,ll key,ll cur) 53 { 54 ll L=tree[cur].l,R=tree[cur].r; 55 if(l<=L&&r>=R){ 56 tree[cur].val+=(R-L+1)*key; 57 tree[cur].add+=key; 58 return; 59 } 60 down(cur,R-L+1); 61 ll mid=(L+R)/2; 62 if(l<=mid) update(l,r,key,cur<<1); 63 if(r>mid) update(l,r,key,cur<<1|1); 64 pushup(cur); 65 } 66 int main() 67 { 68 ll n,m; 69 scanf("%lld%lld",&n,&m); 70 for(ll i=1;i<=n;i++) 71 scanf("%lld",&ary[i]); 72 build(1,n,1); 73 while(m--){ 74 char tmp; 75 cin>>tmp; 76 if(tmp=='Q'){ 77 ll l,r; 78 scanf("%lld%lld",&l,&r); 79 ll ans=query(l,r,1); 80 printf("%lld\n",ans); 81 } 82 else{ 83 ll l,r,key; 84 scanf("%lld%lld%lld",&l,&r,&key); 85 update(l,r,key,1); 86 } 87 } 88 return 0; 89 }