原题链接 题意:给定一个初始为0的矩阵,每次可以使一个方块内的数由0变成1或者由1变成0,询问某一点是1还是0 思路:普通修改肯定过不了,但是有一点,某一个点如果被改变k次那么这个点就是k&1或者说k%2。基于这个思路,我们可以用树状数组方便地得出某一个点被修改过多少次。假设sum[i][j]可以求得i,j这个点被改变的次数,那么如果我们给出
12 2C 1 1 2 2Q 2 2这组数据,那么我们我们可以先让sum[i][j]成为如下的样子 x/y 1 2 3 4 1 1 1 1 1 2 1 1 1 1 3 1 1 1 1 4 1 1 1 1 接下来让y>=3的部分全减去1 x/y 1 2 3 4 1 1 1 0 0 2 1 1 0 0 3 1 1 0 0 4 1 1 0 0 接下来让x>=3的部分全减去1 x/y 1 2 3 4 1 1 1 0 0 2 1 1 0 0 3 0 0 -1 -1 4 0 0 -1 -1 接下来让x>=3,y>=3的部分全加上1 x/y 1 2 3 4 1 1 1 0 0 2 1 1 0 0 3 0 0 0 0 4 0 0 0 0 这不就是我们想要的将左上角为(1,1),右下角为(2,2)的部分全变成1的效果吗?但是sum这个函数的结果是这个样子,但是实际上对于用来存储数据的bit数组却不是这个样子,它略有不同他是这个样子的
1 1 0 1 1 1 0 1 0 0 0 0 1 1 0 1 1 1 -1 0 1 1 -1 0 0 0 0 0 1 1 -1 0 1 1 -1 0 1 1 -1 0 -1 -1 0 -1 0 0 -1 -1 1 1 -1 0 1 1 -1 0 -1 -1 1 0 0 0 0 0但是执行对于树状数组的求和操作的时候出来的结果就是之前的那些矩阵了 代码如下
#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int maxn = 1005;int bit[maxn][maxn];int K,n,m;int lowbit(int x){ return x & -x;}void add(int x,int y,int v){ for(int i=x;i<=10;i+=lowbit(i)) for(int j=y;j<=10;j+=lowbit(j)) bit[i][j]+=v;}int query(int x,int y){ int s; for(int i=x;i>0;i-=lowbit(i)) for(int j=y;j>0;j-=lowbit(j)) s += bit[i][j]; return s;}int main(){ cin >> K; while(K--){ cin >> n >> m; memset(bit,0,sizeof(bit)); while(m--){ char ch; cin >> ch; if(ch=='C'){ int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); x2++;y2++; add(x1,y1,1); add(x1,y2,-1); add(x2,y1,-1); add(x2,y2,1); } else{ int x,y; scanf("%d%d",&x,&y); cout << (query(x,y)&1) << endl; } } cout << endl; }}新闻热点
疑难解答