POJ 2155 Matrix 二维线段树 奇妙的成段更新 单点查询

来源:互联网 发布:王自如和雷军 知乎 编辑:程序博客网 时间:2024/06/17 14:06
//POJ 2155 Matrix 二维线段树 奇妙的成段更新 单点查询/*题意:有一个n*n的矩阵,初始化全部为0。有2中操作;1、给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成02、询问某点的值思路:二维线段树,一维线段树的成段更新需要lazy。引申到二维线段树应该需要一个lazy,一个sublazy,可是这里什么都不用。奇妙之处在于这题的操作是异或,当某一段区间需要异或操作时候,不必更新到它所有的叶子结点,可以像lazy那样父结点异或后就返回只要在查询时从根节点开始异或,而不是直接查叶子结点,这样相当于将lazy储存在父结点上*/#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 1005#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,rint sum[N<<2][N<<2];int n,m,ans;void SubBuild(int rt,int l,int r,int t){sum[t][rt] = 0;if(l!=r){int mid = (l + r) >> 1;SubBuild(lson,t);SubBuild(rson,t);}}void Build(int rt,int l,int r){SubBuild(1,1,n,rt);if(l != r){int mid = (l + r) >> 1;Build(lson);Build(rson);}}void SubUpdate(int rt,int l,int r,int LY,int RY,int t){if(LY <= l && RY >= r)sum[t][rt] ^= 1;else{int mid = (l + r) >> 1;if(LY <= mid) SubUpdate(lson,LY,RY,t);if(RY >  mid) SubUpdate(rson,LY,RY,t);}}void Update(int rt,int l,int r,int LX,int RX,int LY,int RY){if(LX <= l && RX >= r)SubUpdate(1,1,n,LY,RY,rt);else{int mid = (l + r) >> 1;if(LX <= mid) Update(lson,LX,RX,LY,RY);if(RX >  mid) Update(rson,LX,RX,LY,RY);}}void SubQuery(int rt,int l,int r,int y,int t){ans ^= sum[t][rt];//这里是异或!!!if(l!=r){int mid = (l + r) >> 1;if(y <= mid) SubQuery(lson,y,t);else SubQuery(rson,y,t);}}void Query(int rt,int l,int r,int x,int y){SubQuery(1,1,n,y,rt);if(l!=r){int mid = (l + r) >> 1;if(x <= mid) Query(lson,x,y);else Query(rson,x,y);}}int main(){int T,ca = 1;char op[5];int a,b,c,d;scanf("%d",&T);while(T--){scanf("%d %d",&n,&m);Build(1,1,n);if(ca++ != 1)puts("");while(m--){scanf("%s",op);if(op[0] == 'C'){scanf("%d %d %d %d",&a,&b,&c,&d);Update(1,1,n,a,c,b,d);}else{scanf("%d %d",&a,&b);ans = 0;Query(1,1,n,a,b);printf("%d\n",ans);}}}return 0;}

原创粉丝点击