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("");
        }
    }
  • 相关阅读:
    php 构造函数支持不同个数参数的方法
    浅谈管理系统操作日志设计(附操作日志类)
    PHP 远程文件下载的进度条实现
    PHP处理大文件下载
    c语言线性表
    c语言题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点
    c语言:从一组数据中选出可以组成三角形并且周长最长的三个数(简单)
    关于Staruml与powerdesigner启动使用中的问题
    Win7下安装Apache+PHP+MySQL
    <转>java编译问题:使用了未经检查或不安全的操作
  • 原文地址:https://www.cnblogs.com/lastone/p/5296028.html
Copyright © 2011-2022 走看看