poj3468 A Simple Problem with Integers
1 #include<stdio.h> 2 #define N 100010 3 struct node{ 4 int l,r; 5 __int64 inc,sum;//注意要定义为__int64型 6 }tree[3*N]; 7 int num[N]; 8 void build(int l,int r,int i)//建立线段树 9 { 10 tree[i].l=l; 11 tree[i].r=r; 12 tree[i].inc=0; 13 if(l==r){ 14 tree[i].sum=num[l];//叶子节点赋值 15 return; 16 } 17 int mid=(l+r)>>1; 18 build(l,mid,i<<1); 19 build(mid+1,r,(i<<1)+1); 20 tree[i].sum=tree[i<<1].sum+tree[(i<<1)+1].sum;//回归时给非叶子节点赋值 21 } 22 void update(int l,int r,int inc,int i)//l~r段的节点元素值增加inc 23 { 24 if(l==tree[i].l&&tree[i].r==r){//假如找到这段,则此节点inc域增加 25 tree[i].inc+=inc; 26 return; 27 }else{//否则说明此节点包括此段,则直接让其sum域这一段的增量 28 tree[i].sum+=(r-l+1)*inc; 29 } 30 int mid=(tree[i].l+tree[i].r)>>1; 31 if(r<=mid) update(l,r,inc,i<<1); 32 else if(l>mid) update(l,r,inc,(i<<1)+1); 33 else{ 34 update(l,mid,inc,i<<1); 35 update(mid+1,r,inc,(i<<1)+1); 36 } 37 } 38 __int64 query(int l,int r,int i)//查询l~r段元素的和 39 { 40 __int64 sum=0; 41 if(l==tree[i].l&&tree[i].r==r){//找到此段直接加到sum上 42 sum+=tree[i].sum+(r-l+1)*tree[i].inc; 43 return sum; 44 } 45 if(tree[i].inc){//往下消除增量 46 int t=i<<1; 47 tree[t].inc+=tree[i].inc; 48 tree[t+1].inc+=tree[i].inc; 49 tree[i].sum+=(tree[i].r-tree[i].l+1)*tree[i].inc; 50 tree[i].inc=0;//记得置零 51 } 52 int mid=(tree[i].l+tree[i].r)>>1; 53 if(r<=mid) sum+=query(l,r,i<<1); 54 else if(l>mid) sum+=query(l,r,(i<<1)+1); 55 else{ 56 sum+=query(l,mid,i<<1); 57 sum+=query(mid+1,r,(i<<1)+1); 58 } 59 return sum; 60 } 61 int main() 62 { 63 int i,a,b,n,inc,Q; 64 char c; 65 scanf("%d%d",&n,&Q); 66 for(i=1;i<=n;++i) 67 scanf("%d",&num[i]); 68 build(1,n,1); 69 while(Q--){ 70 scanf("%*c%c%d%d",&c,&a,&b); 71 if(c=='Q') printf("%I64d\n",query(a,b,1)); 72 else{ 73 scanf("%d",&inc); 74 update(a,b,inc,1); 75 } 76 } 77 return 0; 78 }