点击打开查看论文 这篇论文详细介绍了树状数组和二进制思想的巧妙,读后很受启发。
在下面整理了区间更新,单点查询的模板,分别对应于二维、三维树状数组。
1.二维树状数组poj 2155 Matrix
#include
#include
#include
using namespace std;
const int maxn=1010;
int n;
int c[maxn][maxn];
int lowbit(int k)
{
return k&(-k);
}
void update(int x,int y,int v)
{
while(x<=n)
{
int j=y;
while(j<=n)
{
c[x][j]+=v;
j+=lowbit(j);
}
x+=lowbit(x);
}
}
int getsum(int x,int y)
{
int cnt=0;
while(x>0)
{
int j=y;
while(j>0)
{
cnt+=c[x][j];
j-=lowbit(j);
}
x-=lowbit(x);
}
return cnt;
}
int main()
{
int t,q;
int x,y,xx,yy;
scanf("%d",&t);
while(t--)
{
memset(c,0,sizeof(c));
scanf("%d%d",&n,&q);
while(q--)
{
char c;
cin>>c;
if(c=='C')
{
scanf("%d%d%d%d",&x,&y,&xx,&yy);
x++;y++;xx++;yy++;
update(x,y,1);
update(x,yy+1,1);
update(xx+1,y,1);
update(xx+1,yy+1,1);
}
else if(c=='Q')
{
scanf("%d%d",&x,&y);
x++;y++;
printf("%d\n",getsum(x,y)%2);
}
}
if(t) printf("\n");
}
return 0;
}
2.三维树状数组 hdu 3584 Cube
#include
#include
#include
using namespace std;
const int maxn=110;
int n;
int c[maxn][maxn][maxn];
int lowbit(int k)
{return k&(-k);}
void update(int x,int y,int z,int v)
{
int i,j,k;
for(i=x;i for(j=y;j for(k=z;k {
c[i][j][k]+=v;
}
}
int getsum(int x,int y,int z)
{
int i,j,k;
int cnt=0;
for(i=x;i>0;i-=lowbit(i))
for(j=y;j>0;j-=lowbit(j))
for(k=z;k>0;k-=lowbit(k))
cnt+=c[i][j][k];
return cnt;
}
int main()
{
int m,f;
int x,y,z,xx,yy,zz;
while(~scanf("%d%d",&n,&m))
{
memset(c,0,sizeof(c));
while(m--)
{
scanf("%d",&f);
if(f==1)
{
scanf("%d%d%d%d%d%d",&x,&y,&z,&xx,&yy,&zz);
x++;y++;z++;
xx++;yy++;zz++;
update(x,y,z,1);
update(x,yy+1,zz+1,1);
update(xx+1,y,zz+1,1);
update(xx+1,yy+1,z,1);
update(x,y,zz+1,1);
update(x,yy+1,z,1);
update(xx+1,y,z,1);
update(xx+1,yy+1,zz+1,1);
}
else if(f==0)
{
scanf("%d%d%d",&x,&y,&z);
x++;y++;z++;
printf("%d\n",getsum(x,y,z)%2);
}
}
}
return 0;
}