二维树状数组

来源:互联网 发布:护士系列txt网络作家 编辑:程序博客网 时间:2024/05/22 17:39

一:

一维树状数组:

C[n] = A[n – 2^k + 1] + ... + A[n]

二维树状数组的定义:

C[n][m] = A[n-2^k1+1][m-2^k2+1]+.....+A[n-2^k1+1][m]

                 ......

                 ......

                 A[n][m-2^k2+1]+....................+A[n][m];

二:操作变化

lowbit不变 

int lowbit(int t) {return t&(-t);}

getsum以及update变为二维的循环

void update(int x,int y,int num){for(int i=x;i<=r;i+=lowbit(i)){for(int j=y;j<=c;j+=lowbit(j)){c[i][j]+=num;}}}int getsum(int x,int y){int res=0;for(int i=x;i>0;i-=lowbit(i)){for(int j=y;j>0;j-=lowbit(j)){res+=c[i][j];}}return res;}


三:关于容斥原理

1.要使getsum(i,j)=A[i,j],根据容斥原理,只需要c[i,j]=c[i+1,j+1]=num, c[i+1,j]=c[i,j+1]=-num 即可

2.对于(x1,y1)->(x2,y2)的矩阵都加k,则根据容斥原理只要a[x1,y1]和a[x2+1,y2+1]+k,a[x1][y2+1]和a[x2+1][y1]-k即可


四:zoj3284

两种操作,一种索值

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAX=105;int r,c;int in[MAX][MAX];int lowbit(int t) {return t&(-t);}void update(int x,int y,int num){for(int i=x;i<=r;i+=lowbit(i)){for(int j=y;j<=c;j+=lowbit(j)){in[i][j]+=num;}}}int getsum(int x,int y){int res=0;for(int i=x;i>0;i-=lowbit(i)){for(int j=y;j>0;j-=lowbit(j)){res+=in[i][j];}}return res;}void matadd(int x1,int y1,int x2,int y2,int num){update(x1,y1,num);update(x2+1,y1,-num);update(x1,y2+1,-num);update(x2+1,y2+1,num);}int main(){int query,p,x1,x2,y1,y2,t;int cas=0;while(scanf("%d%d",&r,&c)!=EOF){memset(in,0,sizeof(in));for(int i=1;i<=r;i++){for(int j=1;j<=c;j++){scanf("%d",&t);matadd(i,j,i,j,t);}}printf("Case %d\n",++cas);scanf("%d",&query);while(query--){scanf("%d",&p);if(p==0) {scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&t);if(x1!=x2) matadd(x1+1,1,x2,c,t);matadd(x1,y1,x1,c,t);matadd(x2,y2+1,x2,c,-t);}else if(p==1){scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&t);if(y1!=y2) matadd(1,y1+1,r,y2,t);matadd(x1,y1,r,y1,t);matadd(x2+1,y2,r,y2,-t);}else{scanf("%d%d",&x1,&y1);int ans=getsum(x1,y1);printf("%d\n",ans);}}}return 0;}


0 0
原创粉丝点击