POJ - 2155 Matrix(二维线段树)

点我看题

题意:一个初始值全为0的N×N的矩阵,现在我们可以对矩阵进行两个操作,C x1 y2 x2 y2((x1,y1)在左上角,(x2,y2)在右下角)为把(x1,y1)和(x2,y2)之间的矩阵对应值改为与原来相反的,Q x y为查询(x,y)的值。

分析:目测是二维线段树的基础题,感觉二维线段树和一维线段树的关系有点像二维数组和一维数组的关系一样,那么对于这个题,我们可以先用线段树存下每一行,然后每个叶子结点再存下每一行的具体值,其实操作跟一维的类似。

参考代码:

/*二维线段树的更新*/
#include
#include
#include
#include
#include

using namespace std;
#define lsonx rtx<<1
#define rsonx rtx<<1|1
#define lsony rty<<1
#define rsony rty<<1|1
const int maxn = 1e3+10;
int n,q;
struct SegTreeY{
        int l,r;
        int val;
};
struct SegTreeX{
        int l,r;
        SegTreeY sty[maxn<<2];
};
SegTreeX stx[maxn<<2];
int ans;

void Buildy( int l, int r, int rty, int rtx)
{
    stx[rtx].sty[rty].l = l;
    stx[rtx].sty[rty].r = r;
    stx[rtx].sty[rty].val = 0;
    if( l == r)
        return;
    int mid = (l+r)>>1;
    Buildy(l,mid,lsony,rtx);
    Buildy(mid+1,r,rsony,rtx);
}

void Buildx( int l, int r, int rtx)
{
    stx[rtx].l = l;
    stx[rtx].r = r;
    Buildy(1,n,1,rtx);
    if( l == r)
        return;
    int mid = (l+r)>>1;
    Buildx(l,mid,lsonx);
    Buildx(mid+1,r,rsonx);
}

void Updatey( int y1, int y2, int rty, int rtx)
{
    if( y1 == stx[rtx].sty[rty].l && y2 == stx[rtx].sty[rty].r)
    {
        stx[rtx].sty[rty].val = !stx[rtx].sty[rty].val;
        return;
    }
    int mid = (stx[rtx].sty[rty].l+stx[rtx].sty[rty].r)>>1;
    if( y2 <= mid)
        Updatey(y1,y2,lsony,rtx);
    else if( y1 > mid)
        Updatey(y1,y2,rsony,rtx);
    else
    {
        Updatey(y1,mid,lsony,rtx);
        Updatey(mid+1,y2,rsony,rtx);
    }
}

void Updatex( int x1, int y1, int x2, int y2, int rtx)
{
    if( x1 == stx[rtx].l && x2 == stx[rtx].r)
    {
        Updatey(y1,y2,1,rtx);
        return;
    }

    int mid = (stx[rtx].l+stx[rtx].r)>>1;
    if( x2 <= mid)
        Updatex(x1,y1,x2,y2,lsonx);
    else if( x1 > mid)
        Updatex(x1,y1,x2,y2,rsonx);
    else
    {
        Updatex(x1,y1,mid,y2,lsonx);
        Updatex(mid+1,y1,x2,y2,rsonx);
    }
}

void Queryy( int y, int rty, int rtx)
{
    ans ^= stx[rtx].sty[rty].val;
    if( stx[rtx].sty[rty].l == stx[rtx].sty[rty].r)
        return;
    int mid = (stx[rtx].sty[rty].l+stx[rtx].sty[rty].r)>>1;
    if( y <= mid)
        Queryy(y,lsony,rtx);
    else
        Queryy(y,rsony,rtx);
}

void Queryx( int x, int y, int rtx)
{
    Queryy(y,1,rtx);
    if( stx[rtx].l == stx[rtx].r)
        return;
    int mid = (stx[rtx].l+stx[rtx].r)>>1;
    if( x <= mid)
        Queryx(x,y,lsonx);
    else
        Queryx(x,y,rsonx);
}

int main()
{
    int T;
    scanf("%d",&T);
    while( T--)
    {
        scanf("%d%d",&n,&q);
        Buildx(1,n,1);
        char op[5];
        int x,y;
        int x1,y1,x2,y2;
        while( q--)
        {
            scanf("%s",op);
            if( op[0] == 'C')
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                Updatex(x1,y1,x2,y2,1);
            }
            else if( op[0] == 'Q')
            {
                scanf("%d%d",&x,&y);
                ans = 0;
                Queryx(x,y,1);
                printf("%d\n",ans);
            }
        }
        if( T)
            puts("");
    }

    return 0;
}


你可能感兴趣的:(数据结构--线段树)