poj 2155 二维线段树

在一个二维数组中,每次对一个矩形内所有数据进行取反操作,并实时询问某一位置的值。

一般线段树只支持对一维数据进行更新和查询,但是这题给的是二维数据啊!

这里就需要用到二维线段树了,即树套树,外层线段树的每个结点里面都有一颗线段树。

在实现二维线段树的时候,一开始用加build函数的方式,记录每个结点左右孩子的编号,但超内存了,所以直接用二维数组表示二维线段树,左右孩子编号通过计算得到:设父亲结点为O,左孩子结点就是O*2,右孩子结点就是O*2+1。

这样既省去了建树的时间,也省去了存储左右孩子编号的空间。但是要注意的是这时候数组要开到MAXN*4,而平时只需要开到MAXN*2,因为这里的计算左右孩子结点的方法无疑是浪费了一些空间的。

 

 

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN = 1002;
int n;
bool tree[MAXN*4][MAXN*4];
void updy(bool *tree,int cur,int curl,int curr,int l,int r){
    if(curl==l&&curr==r) {
        tree[cur] = !tree[cur];
        return;
    }
    int mid = (curl+curr)>>1;
    if(l>=mid+1) updy(tree,cur*2+1,mid+1,curr,l,r);
    else if(r<=mid) updy(tree,cur*2,curl,mid,l,r);
    else {
        updy(tree,cur*2+1,mid+1,curr,mid+1,r);
        updy(tree,cur*2,curl,mid,l,mid);
    }
}
void upd(int cur,int curl,int curr,int l,int r,int y1,int y2){
    if(curl==l&&curr==r) {
        updy(tree[cur],1,1,n,y1,y2);
        return;
    }
    int mid = (curl+curr)>>1;
    if(l>=mid+1) upd(cur*2+1,mid+1,curr,l,r,y1,y2);
    else if(r<=mid) upd(cur*2,curl,mid,l,r,y1,y2);
    else {
        upd(cur*2+1,mid+1,curr,mid+1,r,y1,y2);
        upd(cur*2,curl,mid,l,mid,y1,y2);
    }
}
bool queryy(bool *tree,int cur,int curl,int curr,int l){
    if(curl==curr) {
        return tree[cur];
    }
    int mid = (curl+curr)>>1;
    if(l>=mid+1) return tree[cur]^queryy(tree,cur*2+1,mid+1,curr,l);
    else if(l<=mid) return tree[cur]^queryy(tree,cur*2,curl,mid,l);
}
bool query(int cur,int curl,int curr,int l,int r){
    if(curl==curr) {
        return queryy(tree[cur],1,1,n,r);
    }
    int mid = (curl+curr)>>1;
    if(l>=mid+1) return queryy(tree[cur],1,1,n,r)^query(cur*2+1,mid+1,curr,l,r);
    else if(l<=mid) return queryy(tree[cur],1,1,n,r)^query(cur*2,curl,mid,l,r);
}
int main()
{
    int T,X,lx,ly,rx,ry;
    scanf("%d",&X);
    char op[10];
    while(X--&&scanf("%d%d",&n,&T)!=EOF)
    {
        memset(tree,0,sizeof(tree));
        while(T--)
        {
            scanf("%s",op);
            if(op[0]=='C')
            {
                scanf("%d%d%d%d",&lx,&ly,&rx,&ry);
                upd(1,1,n,lx,rx,ly,ry);
            }
            else
            {
                scanf("%d%d",&lx,&ly);
                printf("%d\n",query(1,1,n,lx,ly));
            }
        }
        puts("");
    }
}
posted @ 2016-03-19 19:16  ZhMZ  阅读(298)  评论(0编辑  收藏  举报