树状数组

区间更新:

 //CODE CJOJ 1404
1
#include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define ll long long 5 using namespace std; 6 ll c[100005],c1[100005],d[100005]; //d是贡献值,C是贡献值的树状数组,C1是贡献值乘以I的树状数组 7 ll sum[100005]; 8 int n,q; 9 int lowbit(int x){ 10 return x&(-x); 11 } 12 void add1(int x,ll zhi){ 13 for(int i=x;i<=n;i+=lowbit(i)) 14 c[i]+=zhi; 15 } 16 void add2(int x,ll zhi){ 17 for(int i=x;i<=n;i+=lowbit(i)) 18 c1[i]+=zhi; 19 } 20 ll getsum1(int x){ 21 ll ret=0; 22 for(int i=x;i>0;i-=lowbit(i)) 23 ret+=c[i]; 24 return ret; 25 } 26 ll getsum2(int x){ 27 ll ret=0; 28 for(int i=x;i>0;i-=lowbit(i)) 29 ret+=c1[i]; 30 return ret; 31 } 32 void add(int x,int y,ll w){ 33 d[x]+=w; 34 d[y+1]-=w; 35 add1(x,w);; 36 add1(y+1,-w); 37 add2(x,(ll)x*w); 38 add2(y+1,(ll)-(y+1)*w); 39 } 40 int main(){ 41 freopen("shulieb.in","r",stdin); 42 freopen("shulieb.out","w",stdout); 43 scanf("%d",&n); 44 for(int i=1;i<=n;i++){ 45 register int x; 46 scanf("%d",&x); 47 sum[i]+=sum[i-1]+x; 48 } 49 scanf("%d",&q); 50 for(int i=1;i<=q;i++){ 51 register char a[10]; 52 scanf("%s",a); 53 if(a[0]=='A'){ 54 register int x,y; 55 ll w; 56 scanf("%d%d%lld",&x,&y,&w); 57 add(x,y,w); 58 } else{ 59 register int x; 60 scanf("%d",&x); 61 ll xx=sum[x]+(ll)(x+1)*getsum1(x)-getsum2(x); 62 ll yy=sum[x-1]+(ll)x*getsum1(x-1)-getsum2(x-1); 63 printf("%lld\n",(ll)xx-yy); 64 } 65 } 66 }

二维树状数组:

 1 //CJOJ 1294
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<iostream>
 6 using namespace std;
 7 int lowbit(int x){
 8     return x&(-x);
 9 }
10 int n;
11 int c[1030][1030];
12 void add(int x,int y,int z){
13     for(int i=x;i<=n;i+=lowbit(i))
14     for(int j=y;j<=n;j+=lowbit(j))
15         c[i][j]+=z;
16 }
17 int jisuan(int x,int y){
18     int tot=0;
19     for(int i=x;i>0;i-=lowbit(i))
20     for(int j=y;j>0;j-=lowbit(j))
21         tot+=c[i][j];
22     return tot;
23 }
24 int main(){
25     freopen("1.in","r",stdin);
26     freopen("1.out","w",stdout);
27     int type;
28     while(scanf("%d",&type)!=EOF&&type!=3){
29     //lowbit(0)会死循环!!!需将坐标都转化到(1-N中去)
30     if(type==0) scanf("%d",&n);
31     else if(type==1){
32         register int x,y,a;
33         scanf("%d%d%d",&x,&y,&a);
34         x++,y++;
35         add(x,y,a);
36     } else if(type==2){
37         register int x1,x2,y1,y2;
38         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
39         x1++,x2++,y1++,y2++;
40         printf("%d\n",jisuan(x2,y2)-jisuan(x2,y1-1)-jisuan(x1-1,y2)+jisuan(x1-1,y1-1));
41     }
42     }
43 }

 

posted @ 2017-04-08 13:13  nfy_algorithm  阅读(169)  评论(0编辑  收藏  举报