您的位置:首页 > 理论基础 > 数据结构算法

POJ2155 Matrix(二维线段树)

2016-06-03 10:56 501 查看
题目大意:

有一个n*n的由零组成的矩阵,给定q个操作,C为将x1y1为左下角,x2y2为右下角的矩阵取反值。Q为输出xy的的0,1状态。

思路:二维线段树(树套树)的建造和访问:

# include<stdio.h>
# include<stdlib.h>
# include<string.h>
int a[4010][4010],n,m,ans;
char s[1000];
void buildy(int t,int r,int l,int k,int y1,int y2){//第二维建造
if(r==y1 && l==y2){
a[t][k]^=1;
return;
}
if((r+l)/2>=y2)
buildy(t,r,(r+l)/2,k*2,y1,y2);
else
if(y1>(r+l)/2)
buildy(t,(r+l)/2+1,l,k*2+1,y1,y2);
else
{
buildy(t,r,(r+l)/2,k*2,y1,(r+l)/2);
buildy(t,(r+l)/2+1,l,k*2+1,(r+l)/2+1,y2);
}
}

void buildx(int t,int r,int l,int x1, int y1, int x2, int y2){//建树
if(r==x1 && l==x2){
buildy(t,1,n,1,y1,y2);
return;
}
if((r+l)/2>=x2)
buildx(2*t,r,(r+l)/2,x1,y1,x2,y2);
else
if(x1>(r+l)/2)
buildx(2*t+1,(r+l)/2+1,l,x1,y1,x2,y2);
else
{
buildx(2*t,r,(r+l)/2,x1,y1,(r+l)/2,y2);
buildx(2*t+1,(r+l)/2+1,l,(l+r)/2+1,y1,x2,y2);
}
}
void findy(int t,int r,int l,int k,int y){//查询二维
ans^=a[t][k];
if(l==r)return;
if((r+l)/2>=y){
findy(t,r,(r+l)/2,k*2,y);
}
else
findy(t,(r+l)/2+1,l,k*2+1,y);
}
void findx(int t,int r,int l,int x,int y){//查询
findy(t,1,n,1,y);
if(r==l)return;
if((r+l)/2>=x)
findx(t*2,r,(r+l)/2,x,y);
else
findx(t*2+1,(r+l)/2+1,l,x,y);
}
int main(){
int l,i,t,x1,x2,y1,y2,x,y,c;
scanf("%d",&t);
for(l=1;l<=t;l++){
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%s",s);
if(*s=='C'){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
buildx(1,1,n,x1,y1,x2,y2);

}else{
ans=0;
scanf("%d%d",&x,&y);
findx(1,1,n,x,y);
printf("%d\n",ans);//输出
}
}
if(l<t)puts("");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息