zoukankan      html  css  js  c++  java
  • 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
    ",query(1,1,n,lx,ly));
                }
            }
            puts("");
        }
    }
  • 相关阅读:
    mac+chrome 最常用快捷键
    关于<form> autocomplete 属性
    MAC vim修改hosts文件
    git 使用详解(3)—— 最基本命令 + .gitignore 文件
    git 使用详解(2)——安装+配置+获取帮助
    vue动态生成组件
    slot插槽
    provide 和 inject高阶使用
    js正则验证表达式验证
    angular常用命令整理
  • 原文地址:https://www.cnblogs.com/lastone/p/5296028.html
Copyright © 2011-2022 走看看