您的位置:首页 > 其它

poj 2155 (二维线段树的成段更新)

2014-07-20 16:07 239 查看
题意:

原矩形所有的元素都为0,改变一个子矩形 ,使该矩形上的0变1,1变0,询问某一点为多少。

解题思路:

利用二维线段树域值C来记录某个该矩形经过几次操作,然后在询问时算操作的总数即可,奇数为1,偶数相反。

注意:



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXN0 1001
#define l1(x) (x)<<1
#define r1(x) (x)>>1
struct TRnodesub{
int yL,yR,c;
bool lazy;
bool equal(int ll,int rr){
return (ll==yL)&&(rr==yR);
}
void set(int ll,int rr){
yL = ll;
yR = rr;
}
int getmid(){
return (yL+yR)>>1;
}
};
struct TRnode{
int xL,xR;
void set(int ll,int rr){
xL = ll;
xR = rr;
}
TRnodesub TRsub[2050];
};
TRnode TR[2050];
void pd(int k,int k1,int k11,int fak){
TR[fak].TRsub[k1].c+=TR[fak].TRsub[k].c;
TR[fak].TRsub[k11].c+=TR[fak].TRsub[k].c;
TR[fak].TRsub[k1].lazy = TR[fak].TRsub[k11].lazy = TR[fak].TRsub[k].lazy;
TR[fak].TRsub[k].lazy = 0;
TR[fak].TRsub[k].c = 0;
}
void buildsub(int yL,int yR,int k,int ksub){
TR[k].TRsub[ksub].set(yL,yR);
TR[k].TRsub[ksub].lazy = false;
TR[k].TRsub[ksub].c=0;
if(yL==yR){
return;
}
int midsub;
if(TR[k].TRsub[ksub].lazy){
pd(ksub,2*ksub,2*ksub+1,k);
}
midsub = r1(yL+yR);
if(midsub>=yR){
buildsub(yL, yR, k, 2*ksub);
}
else if(midsub<yL){
buildsub(yL, yR, k, 2*ksub+1);
}
else {
buildsub(yL, midsub, k, 2*ksub);
buildsub(midsub+1, yR, k, 2*ksub+1);
}
}
void build(int xL,int xR,int yL,int yR,int k){
TR[k].set(xL,xR);
if(xL==xR){
buildsub(yL,yR,k,1);
return;
}
int mid = r1(xL+xR);
if(mid>=xR){
build( xL,xR, yL,yR, l1(k));
}
else if(mid<xL){
build( xL,xR, yL,yR, (l1(k))+1);
}
else {
build(xL,mid,yL,yR,l1(k));
build(mid+1,xR,yL,yR,(l1(k))+1);
}
buildsub(yL,yR,k,1);
}
void querysub(int yL,int yR,int k,int ksub,int &ans){
if(TR[k].TRsub[ksub].equal(yL,yR)){
ans += TR[k].TRsub[ksub].c;
return;
}
int midsub;
if(TR[k].TRsub[ksub].lazy){
pd(ksub,2*ksub,2*ksub+1,k);
}
midsub = TR[k].TRsub[ksub].getmid();
if(midsub>=yL){
querysub(yL, yR, k, 2*ksub,ans);
}
else{
querysub(yL, yR, k, 2*ksub+1,ans);
}
}
void query(int xL,int xR,int yL,int yR,int k,int &ans){
if(xL==TR[k].xL&&TR[k].xR==xR){
querysub(yL,yR,k,1,ans);
return;
}
int mid = r1(TR[k].xL+TR[k].xR);
if(mid>=xL){
query(xL, xR, yL, yR, 2*k,ans);
}
else {
query(xL, xR, yL, yR, 2*k+1,ans);
}
querysub(yL,yR,k,1,ans);
//return ans;
}
void updatesub(int xL,int xR,int yL,int yR,int k,int ksub){
if(TR[k].TRsub[ksub].equal(yL, yR)){
if(TR[k].xL==xL&&TR[k].xR==xR){
TR[k].TRsub[ksub].lazy = 1;
++TR[k].TRsub[ksub].c;
}
return;
}
int midsub;
if(TR[k].TRsub[ksub].lazy){
pd(ksub,ksub<<1,ksub<<1|1,k);
}
midsub = TR[k].TRsub[ksub].getmid();
if(midsub>=yR){
updatesub(xL,xR,yL, yR, k, ksub<<1);
}
else if(midsub<yL){
updatesub(xL,xR,yL, yR, k, ksub<<1|1);
}
else {
updatesub(xL,xR,yL, midsub, k, ksub<<1);
updatesub(xL,xR,midsub+1, yR, k, ksub<<1|1);
}
}
void update(int xL,int xR,int yL,int yR,int k){
if(xL==TR[k].xL&&TR[k].xR==xR){
updatesub(xL,xR,yL,yR,k,1);
return;
}
int mid = r1(TR[k].xL+TR[k].xR);
if(mid>=xR){
update( xL,xR, yL,yR, k<<1);
}
else if(mid<xL){
update( xL,xR, yL,yR, k<<1|1);
}
else {
update(xL,mid,yL,yR,k<<1);
update(mid+1,xR,yL,yR,k<<1|1);
}
//updatesub(xL,xR,yL,yR,k,1);
}
int main(){
int X,N,F;
char w[2];
int x,y,x1,y1,x2,y2;
scanf("%d",&X);
while(X--){
scanf("%d%d",&N,&F);
build(1, N, 1, N, 1);
for(int i=0;i<F;++i){
scanf("%s",w);
if(w[0]=='Q'){
scanf("%d%d",&x,&y);
int ans = 0;
query(x, x, y, y, 1,ans);
printf("%d\n",ans&1);
}
else {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update(x1,x2,y1,y2,1);
}

}
if(X>0)printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: