poj2155 Matrix 二维线段树

二维线段树区间更新和单点查询,由于二维线段树不能传递标记,所以区间更新和一维不太一样,需要用到被更新的值以及更新操作的一些性质,还有要注意对query的影响。

这里操作是翻转,而且是单点查询,所以就直接在矩形块内更新,不把标记传递下去,查询的时候做一下微调,把所有经过的路径的标记都判断一遍,看是否需要翻转,这样就解决了这道题。

上一道是单点更新和区间求和,当然就不用标记了,把所有的第一维的第二层的y点全部更新,查询的时候不用查到最底层也能查到了。

二维线段树还是比较灵活,但这已经是最简单的树套树了。。。orz那些会各种线段树套平衡树,平衡树套主席树的。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

typedef long long ll;
const int maxn=1200;
const int INF=1e9+10;

int n,q;
char op[5];int x,y,xt,yt;
struct NodeY
{
    int val;
};
struct NodeX
{
    NodeY ty[maxn<<2];
    void build(int l,int r,int rt)
    {
        ty[rt].val=0;
        if(l==r) return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void update(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R){
            ty[rt].val^=1;
            return;
        }
        int m=(l+r)>>1;
        if(L<=m) update(L,R,lson);
        if(R>m) update(L,R,rson);
    }
    int query(int p,int l,int r,int rt)
    {
        if(l==r) return ty[rt].val;
        int m=(l+r)>>1;
        if(p<=m) return ty[rt].val^query(p,lson);
        return ty[rt].val^query(p,rson);
    }
};NodeX tx[maxn<<2];

void build(int l,int r,int rt)
{
    tx[rt].build(1,n,1);
    if(l==r) return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}

void update(int xL,int xR,int yL,int yR,int l,int r,int rt)
{
    if(xL<=l&&r<=xR){
        tx[rt].update(yL,yR,1,n,1);
        return;
    }
    int m=(l+r)>>1;
    if(xL<=m) update(xL,xR,yL,yR,lson);
    if(xR>m) update(xL,xR,yL,yR,rson);
}

int query(int x,int y,int l,int r,int rt)
{
    int res=tx[rt].query(y,1,n,1);
    if(l==r) return res;
    int m=(l+r)>>1;
    if(x<=m) return res^query(x,y,lson);
    return res^query(x,y,rson);
}

int main()
{
    int T;cin>>T;
    while(T--){
        scanf("%d%d",&n,&q);
        build(1,n,1);
        while(q--){
            scanf("%s",op);
            if(op[0]=='C'){
                scanf("%d%d%d%d",&x,&y,&xt,&yt);
                update(x,xt,y,yt,1,n,1);
            }
            else{
                scanf("%d%d",&x,&y);
                printf("%d\n",query(x,y,1,n,1));
            }
        }
        if(T) puts("");
    }
    return 0;
}
View Code

 

posted @ 2016-03-05 14:50  __560  阅读(380)  评论(0编辑  收藏  举报