POJ 3225

基本参考http://blog.csdn.net/metalseed/article/details/8039326

总的来说,敲完一遍理解会更加好一点,标记下传法。

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互换

利用异或值来决定是否要翻转,注意标记下传时,孩子结点的值是否要翻转是根据父结点决定的。由于最新的状态是在最上层完成的,所以后代结点翻转状态基本没有,除了当父结点覆盖状态为-1(此时区间内部分子区间值为1),需要结合父结点来决定当前的异或值。

#include <cstdio>  
#include <cstring>  
#include <cctype>  
#include <iostream>
#include <algorithm>  
using namespace std;    
   
const int maxn = 131072;  
bool hash[maxn+1];  
int cover[maxn<<2];  
int XOR[maxn<<2];

void PushXOR(int rt){
    if(cover[rt]!=-1) cover[rt]^=1;
    else XOR[rt]^=1;
}

void PushDown(int rt){
    if(cover[rt]!=-1){
        cover[rt<<1]=cover[rt<<1|1]=cover[rt];
        XOR[rt<<1]=XOR[rt<<1|1]=0;
        cover[rt]=-1;
    }
    if(XOR[rt]){
        PushXOR(rt<<1);
        PushXOR(rt<<1|1);
        XOR[rt]=0;
    }
}

void update(char op,int L,int R,int l,int r,int rt){
    if(L<=l&&r<=R){
        if(op=='U'){
            cover[rt]=1; XOR[rt]=0;
        }
        else if(op=='D'){
            cover[rt]=0; XOR[rt]=0;
        }
        else if(op=='C'||op=='S'){
            PushXOR(rt);
        }
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(L<=m) update(op,L,R,l,m,rt<<1);
    else if(op=='I'||op=='C'){ cover[rt<<1]=XOR[rt<<1]=0; }
    if(m<R) update(op,L,R,m+1,r,rt<<1|1);
    else if(op=='I'||op=='C'){ cover[rt<<1|1]=XOR[rt<<1|1]=0; }
}

void query(int l,int r,int rt){
    if(cover[rt]!=-1){
        if(cover[rt]>0){
            for(int i=l;i<=r;i++)
            hash[i]=true;
        }
        return ;
    }
    if(l==r) return ;
    PushDown(rt);
    int m=(l+r)>>1;
    query(l,m,rt<<1);
    query(m+1,r,rt<<1|1);
}

int main(){
    cover[1] = XOR[1] = 0;  
    char op , l , r;  
    int a , b;  
 //   int tt=0;
    while (scanf("%c %c%d,%d%c",&op , &l , &a , &b , &r)!=EOF) {
        getchar();
//        tt++;
        a <<= 1 , b <<= 1;  
        if (l == '(') a ++;  
        if (r == ')') b --;  
        if (a > b) {  
            if (op == 'C' || op == 'I') {  
                cover[1] = XOR[1] = 0;  
            }  
        } 
        else update(op , a , b , 0 , maxn , 1);  
//        if(tt==5) break;
    }
    memset(hash,false,sizeof(hash));
    query(0,maxn,1);
    bool flag = false;  
    int s = -1 , e;  
    for (int i = 0 ; i <= maxn ; i ++) {  
        if (hash[i]) {  
            if (s == -1) s = i;  
            e = i;  
        } else {  
            if (s != -1) {  
                if (flag) printf(" ");  
                flag = true;  
                printf("%c%d,%d%c",s&1?'(':'[' , s>>1 , (e+1)>>1 , e&1?')':']');  
                s = -1;  
            }  
        }  
    }  
    if (!flag) printf("empty set");  
    puts("");  
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/jie-dcai/p/4319966.html