Matrix 楼教主出的题目。
题意:一个矩阵初始值都为0,每次给“C X1 Y1 X2 Y2" 去反转这个矩阵。或者"Q X1 Y1"查询这个点是0/1。
第一次接触树套树的题目。
一句AC:对于基本的线段树,再在每个节点建一个y方向上的线段树。tree[n][m]
这道题目更新的时候,对于X方向就是(X1,X2)这个区间,再在其上对Y1,Y2进行更新。
对于查询,X方向上,自顶向下到X1都要对Y进行查询(更新的区间必包括该点),Y方向上则更新到Y1.
#include <stdio.h> #include <string.h> #define MAXN 1005 #define mem(a) memset(a, 0, sizeof(a)) bool tree[MAXN<<2][MAXN<<2]; int X, N, T; int num, X1, X2, Y1, Y2; char ch[10]; void updatey(int yl,int yr,int xp,int yp) { if(Y1<=yl && yr<=Y2) { tree[xp][yp]=!tree[xp][yp]; return; } int mid=(yl+yr)>>1; if(Y1<=mid) updatey(yl,mid,xp,yp<<1); if(Y2>mid ) updatey(mid+1,yr,xp,yp<<1|1); } void updatex(int xl,int xr,int xp) { if(X1<=xl && xr<=X2) { updatey(1,N,xp,1); return; } int mid=(xl+xr)>>1;//下面这句刚开始写错了,按照build写了,忘记是个更新操作... if(X1<=mid) updatex(xl,mid,xp<<1); if(X2>mid) updatex(mid+1,xr,xp<<1|1); } void queryy(int yl,int yr,int xp,int yp) { num+=tree[xp][yp]; if(yl==yr) return; int mid=(yl+yr)>>1; if(Y1<=mid) queryy(yl,mid,xp,yp<<1); else queryy(mid+1,yr,xp,yp<<1|1); } void queryx(int xl,int xr,int xp) { queryy(1,N,xp,1); if(xl==xr) return; int mid=(xl+xr)>>1; if(X1<=mid) queryx(xl,mid,xp<<1); else queryx(mid+1,xr,xp<<1|1); } int main() { while(~scanf("%d", &X))while(X--) { mem(tree); scanf("%d %d%*c", &N,&T); for(int i=0;i<T;i++) { scanf("%s%d%d",ch,&X1,&Y1); if(ch[0]=='Q') num=0,queryx(1,N,1),printf("%d\n",num%2); else { scanf("%d%d",&X2,&Y2); updatex(1,N,1); } } if(X) printf("\n"); } return 0; }
时间: 2024-11-02 01:50:25