• POJ3225 Help with Intervals(区间操作)


    纯属抄袭胡浩大神的题解。。。看了N久才看懂o(╯□╰)o,果然智商拙计,学习到了一种处理开区间的方法(感觉好神奇),当个搬运工。。。

    题目大意:

    区间操作,交,并,补等

    题解:

    我们一个一个操作来分析:(用0和1表示是否包含区间,-1表示该区间内既有包含又有不包含)

    U:把区间[l,r]覆盖成1

    I:把[-∞,l)(r,∞]覆盖成0

    D:把区间[l,r]覆盖成0

    C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换

    S:[l,r]区间0/1互换

    成段覆盖的操作很简单,比较特殊的就是区间0/1互换这个操作,我们可以称之为异或操作

    很明显我们可以知道这个性质:当一个区间被覆盖后,不管之前有没有异或标记都没有意义了

    所以当一个节点得到覆盖标记时把异或标记清空

    而当一个节点得到异或标记的时候,先判断覆盖标记,如果是0或1,直接改变一下覆盖标记,不然的话改变异或标记

    开区间闭区间只要数字乘以2就可以处理(偶数表示端点,奇数表示两端点间的区间)

    线段树功能:update:成段替换,区间异或 query:简单hash

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define lson l , m , s << 1
    #define rson m+1 , r , s << 1 | 1
    #define MAXN 150000
    int setv[MAXN<<2],Xor[MAXN<<2];
    bool hash[MAXN];
    void FXor(int s)
    {
        if(setv[s]!=-1) setv[s]^=1;
        else
            Xor[s]^=1;
    }
    void PushDown(int s)
    {
        if(setv[s]!=-1) {
            setv[s<<1]=setv[s<<1|1]=setv[s];
            Xor[s<<1]=Xor[s<<1|1]=0;
            setv[s]=-1;
        }
        if(Xor[s]==1) {
            FXor(s<<1);
            FXor(s<<1|1);
            Xor[s]=0;
        }
    }
    void update(char op,int ql,int qr,int l,int r,int s)
    {
        if(ql<=l&&r<=qr) {
            if(op=='U') {
                setv[s]=1;
                Xor[s]=0;
            } else if(op=='D') {
                setv[s]=0;
                Xor[s]=0;
            } else if(op=='C'||op=='S')
                FXor(s);
            return;
        }
        PushDown(s);
        int m=(l+r)>>1;
        if(ql<=m) update(op,ql,qr,lson);
        else  if(op=='I'||op=='C') Xor[s<<1]=setv[s<<1]=0;
        if(qr>m) update(op,ql,qr,rson);
        else if(op=='I'||op=='C') Xor[s<<1|1]=setv[s<<1|1]=0;
    }
    void query(int l,int r,int s)
    {
        if(setv[s]==1) {
            for(int i=l; i<=r; i++)
                hash[i]=true;
            return;
        } else if(setv[s]==0) return;
        if(l==r) return;
        PushDown(s);
        int m=(l+r)>>1;
        query(lson);
        query(rson);
    }
    int main(void)
    {
        char op,a,b;
        int l,r;
        setv[1]=Xor[1]=0;
        memset(hash,false,sizeof(hash));
        while(scanf("%c %c%d,%d%c\n",&op,&a,&l,&r,&b)!=EOF) {
            l<<=1;
            r<<=1;
            if(a=='(') l++;
            if(b==')') r--;
            update(op,l,r,0,MAXN,1);
        }
        query(0,MAXN,1);
        int s=-1,t;
        bool flag=false;
        for(int i=0; i<MAXN; i++)
            if(hash[i]) {
                if(s==-1) s=i;
                t=i;
            } else if(s!=-1)  {
                if(flag) printf(" ");
                flag=true;
                printf("%c%d,%d%c",s&1?'(':'[',s>>1,(t+1)>>1,t&1?')':']');
                s=-1;
            }
        if(!flag) printf("empty set");
        printf("\n");
        return 0;
    }

  • 相关阅读:
    error: expected unqualified-id extern "C" {
    cmake交叉编译android(转)
    wwindows文件放入linux后多出换行符
    JNI 引用问题梳理(转)
    OpenCV实现任意大小图片的合并(转)
    android camera preview常用格式
    Linux下找不到动态链接库(转)
    ld链接器的工作原理及链接顺序(转)
    添加静态库入动态库时,符号查找不到的问题
    如何捕获 System.loadLibrary 产生的异常?(转)
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3092085.html
Copyright © 2020-2023  润新知