poj 2155

来源:互联网 发布:造假因子分析数据注意 编辑:程序博客网 时间:2024/06/10 15:11

二维树状数组,区间更新,单点查询。。

树状数组中的
两个函数 Update()修改某个点的值(准确说是某个路径, 递增或递 减),Getsum()
求和区间(1, x)内的点的值。

修改某点 x 和求和某个区间(1, x)是可以互相调
换的,即我们可以用 Getsum(x, c)修改(1, x)这个区间内的点的值,而用
Update(x)来求该点的值。

我们要使区间(a, b)内的点 + c,只需要使区间(1, b)
内的点+c,而区间(1, a-1)内的点-c 即可。如果是二维的,修改矩阵(x1, y1)
到(x2, y2),即(x2, y2)+c, (x1-1,y2)-c, (x2, y1-1)-c, (x1-1,y1-1)+c 即
可。

#include<cstdio>#include<cstring>#define MAXN 1005#define for if(0);else forint c[MAXN][MAXN];int N;int lowbit(int x){return x&(-x);}void update(int i,int j,int v){for(int x=i;x<=N;x+=lowbit(x)){for(int y=j;y<=N;y+=lowbit(y)){c[x][y]+=v;}}}int getsum(int i,int j){int sum=0;for(int x=i;x>0;x-=lowbit(x)){for(int y=j;y>0;y-=lowbit(y)){sum+=c[x][y];}}return sum;}int main(){int t,m;int first=1;scanf("%d",&t);while(t--){if(first)first=0;else puts("");char cmd;int x1,y1,x2,y2;scanf("%d%d",&N,&m);memset(c,0,sizeof(c));while(m--){scanf(" %c",&cmd);if(cmd=='C'){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);update(x1,y1,1);update(x1,y2+1,-1);update(x2+1,y1,-1);update(x2+1,y2+1,1);}else {scanf("%d%d",&x1,&y1);int ans=getsum(x1,y1);if(ans&1)puts("1");else puts("0");}}}}