zoukankan      html  css  js  c++  java
  • POJ 2155 二维线段树 经典的记录所有修改再统一遍历 单点查询

    本来是想找一个二维线段树涉及懒惰标记的,一看这个题,区间修改,单点查询,以为是懒惰标记,敲到一半发现这二维线段树就不适合懒惰标记,你更新了某段的某列,但其实其他段的相应列也要打标记,但因为区间不一样,又不好打。。。也可能是我这是在套用一维线段树的思想,还有更好的二维线段树懒惰标记方法

    反正到现在我还没搞定二维线段树的懒惰标记,因为这道题不用懒惰标记,因为是二进制序列,区间修改仅限于翻转操作,那就只要记录每次操作,最后查询的时候从上往下把所有修改都来上一遍,就可以了。就类似于树状数组的第二种用法,每次区间修改,最后查询的时候把前面的修改都给加起来。

    即区间修改的时候,定位到某段某区间列进行标记,单独查询的时候,针对每个行段的该列所在区间都遍历一遍,把所有的修改都遍历到之后就是结果了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    using namespace std;
    const int N=1010;
    int d[N*3][N*3];
    int flag[N*3][N*3];
    int n,Q;
    void buildc(int k,int rt,int l,int r)
    {
        d[k][rt]=0;
        if (l>=r){
            return;
        }
        int mid=(l+r)>>1;
        buildc(k,lson);
        buildc(k,rson);
    }
    void buildr(int rt,int l,int r)
    {
        buildc(rt,1,1,n);
        if (l>=r){
            return;
        }
        int mid=(l+r)>>1;
        buildr(lson);
        buildr(rson);
    }
    
    void fixc(int k,int c1,int c2,int rt,int l,int r)
    {
        if (c1<=l && r<=c2){
            d[k][rt]^=1;
            return;
        }
        int mid=(l+r)>>1;
        if (c1>mid) fixc(k,c1,c2,rson);
        else
        if (c2<=mid) fixc(k,c1,c2,lson);
        else{
            fixc(k,c1,c2,lson);
            fixc(k,c1,c2,rson);
        }
    }
    void fixr(int r1,int r2,int c1,int c2,int rt,int l,int r)
    {
        if (r1<=l && r<=r2){
            fixc(rt,c1,c2,1,1,n);
            return;
        }
        int mid=(l+r)>>1;
        if (r1>mid) fixr(r1,r2,c1,c2,rson);
        else
        if (r2<=mid) fixr(r1,r2,c1,c2,lson);
        else{
            fixr(r1,r2,c1,c2,lson);
            fixr(r1,r2,c1,c2,rson);
        }
    }
    void queryc(int& ans,int k,int C,int rt,int l,int r)
    {
        if (d[k][rt]){
            ans^=1;
        }
        if (l>=r){
            return ;
        }
        int mid=(l+r)>>1;
        if (mid>=C)
        queryc(ans,k,C,lson);
        else
        queryc(ans,k,C,rson);
    }
    void queryr(int& ans,int R,int C,int rt,int l,int r)
    {
        queryc(ans,rt,C,1,1,n);
        if (l>=r){
            return;
        }
        int mid=(l+r)>>1;
        if (R<=mid)  queryr(ans,R,C,lson);
        else
        queryr(ans,R,C,rson);
    }
    int main()
    {
        char ch[5];
        int a,b,c,d;
        int t;
        scanf("%d",&t);
        while (t--)
        {
           scanf("%d%d",&n,&Q);
           buildr(1,1,n);
           while (Q--)
           {
               scanf("%s",ch);
               if (ch[0]=='C'){
                   scanf("%d%d%d%d",&a,&b,&c,&d);
                   fixr(a,c,b,d,1,1,n);
               }
               else {
                   scanf("%d%d",&a,&b);
                   int ans=0;
                   queryr(ans,a,b,1,1,n);
                   printf("%d
    ",ans);
               }
           }
           if (t) puts("");
        }
        return 0;
    }
    

      

  • 相关阅读:
    UVALive
    hdu 3869 Color the Simple Cycle (kmp+polya计数)
    zoj 3794 Greedy Driver
    zoj 3795 Grouping
    ASP.NET Core 简介
    ASP.NET Core 基础教程
    iOS ShareSDK Scheme
    微博授权失败 redirect_uri_mismatch
    集成友盟分享SDK报错
    获取设备实际宽度
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3864241.html
Copyright © 2011-2022 走看看