[POJ 2155]Matrix
<题意概括>
给定一个N*N的矩阵,矩阵中元素的初始值为0
有两种操作
1,将一个左上端点为[x1,y1],右下端点为[x2,y2]的矩阵中的元素取反
2,询问矩阵中[x,y]处的数值
<做法>
很明显这是一道数据结构的裸题
有两种做法:二维线段树和二维树状数组+差分
这里只讲二维树状数组+差分的做法(其实是本人太蒟蒻了不会二维线段树
用二维树状数组+差分维护矩阵的前缀和 这是基础操作大家都知道
但是取反怎么办呢?
这时我们可以想到对矩阵中的每一个元素维护一个修改次数T
那么所对应的修改次数T为偶数的元素值为0,反之则为1
然后在取反的时候修改[x1,y1],[x1,y2+1],[x2+1,y1],[x2+1,y2+1]处的值就好了
询问时用前缀和求出[x,y]所对应的修改次数T并判断奇偶就行了
<代码>
#include<cstdio> #include<cstring> #define Fast register #define Lowbit(x) (x&(-x)) inline void Scan(int&s){ s=0;Fast char c=getchar(); while(c<48||c>57)c=getchar(); while(c>47&&c<58)s=(s<<3)+(s<<1)+c-48,c=getchar(); } inline void Getopt(char&s){ s=getchar(); while(s!=‘C‘&&s!=‘Q‘)s=getchar(); } int C[1001][1001]; int X,N,T; inline void Update(int&x,int&y,const int&v){ for(Fast int i=x;i<=N;i+=Lowbit(i)){ for(Fast int j=y;j<=N;j+=Lowbit(j)){ C[i][j]+=v; } } } inline int Sum(int&x,int&y){ Fast int sum=0; for(Fast int i=x;i>0;i-=Lowbit(i)){ for(Fast int j=y;j>0;j-=Lowbit(j)){ sum+=C[i][j]; } } return sum; } int main(){ Fast int x1,y1,x2,y2;Fast char opt; Scan(X); while(X--){ Scan(N),Scan(T); memset(C,0,sizeof C); while(T--){ Getopt(opt),Scan(x1),Scan(y1); if(opt!=67)putchar((Sum(x1,y1)&1)+48),putchar(10); else{ Scan(x2),Scan(y2); Update(x1,y1,1),Update(x2+1,y2+1,1); Update(x1,y2+1,1),Update(x2+1,y1,1); } } putchar(10); } return 0; }