标签:
大致题意:给出矩阵左上角和右下角坐标,矩阵里的元素 1变0 ,0 变1,然后给出询问,问某个点是多少.
每次变化操作相当于把区间上的值全加一,然后对查询的结果模二即可
这是树状数组第二种模式的应用:
Up()表示修改区间,Down()表示求单点的值。
Down()表示修改区间,Up()表示求单点的值。
http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees这是TC的教程,最后会介绍这种模式所以把这种模式拓展到二维即可
//4872K 454MS #include<cstdio> #include<algorithm> #include<iostream> #include<cstring> using namespace std; #define M 1100 int tree[M][M]; int n,m; #define lowbit(x) (x&-x) void update(int x,int y) { for(int i=y;i<=n;i+=lowbit(i)) for(int j=x;j<=n;j+=lowbit(j)){ tree[i][j]++; } } int query(int x,int y) { int s=0; //一开始没初始化成0...wa了几次... for(int i=y;i>0;i-=lowbit(i)) for(int j=x;j>0;j-=lowbit(j)){ s+=tree[i][j]; } return s%2; } int main() { int T; scanf("%d",&T); while(T--){ memset(tree,0,sizeof(tree)); scanf("%d%d",&n,&m); while(m--){ char op[5]; scanf("%s",op); if(op[0]=='C'){ int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); update(x1,y1); update(x1,y2+1); update(x2+1,y1); update(x2+1,y2+1); } else{ int x,y; scanf("%d%d",&x,&y); printf("%d\n",query(x,y)); } } if(T) puts(""); } return 0; }
就试着用递减路down()来更新,递增路up()来求单点值,同样正确,但比较难理解
//4872K 454MS #include<cstdio> #include<algorithm> #include<iostream> #include<cstring> using namespace std; #define M 1100 int tree[M][M]; int n,m; #define lowbit(x) (x&-x) void update(int x,int y) //递减路来更新 { for(int i=y;i>0;i-=lowbit(i)) for(int j=x;j>0;j-=lowbit(j)){ tree[i][j]++; } } int query(int x,int y) //递增路来求和 { int s=0; for(int i=y;i<=n;i+=lowbit(i)) for(int j=x;j<=n;j+=lowbit(j)){ s+=tree[i][j]; } return s%2; } int main() { int T; scanf("%d",&T); while(T--){ memset(tree,0,sizeof(tree)); scanf("%d%d",&n,&m); while(m--){ char op[5]; scanf("%s",op); if(op[0]=='C'){ int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); update(x1-1,y1-1); update(x1-1,y2); update(x2,y1-1); update(x2,y2); } else{ int x,y; scanf("%d%d",&x,&y); printf("%d\n",query(x,y)); } } if(T) puts(""); } return 0; }
标签:
原文地址:http://blog.csdn.net/kalilili/article/details/43924789