待解决的问题 POJ 3225 Help with Intervals 线段树 码力

  题目链接: http://poj.org/problem?id=3225

  题目大意: 给出若干区间, 有五种操作方式(区间交, 并, 补等等), 求出最后的区间为多少

  解题思路:  需要考虑的东西太多了, 代码也太复杂, 先记录下来, 以后在做

      我们一个一个操作来分析:(用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                  转自: http://blog.csdn.net/metalseed/article/details/8039326

  代码: 代码也是转自http://blog.csdn.net/metalseed/article/details/8039326

#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1

const int maxn = 131072;
bool hash1[maxn+1];
int cover[maxn<<2];
int XOR[maxn<<2];
void FXOR(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]) {
        FXOR(rt<<1);
        FXOR(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') {
            FXOR(rt);
        }
        return ;
    }
    PushDown(rt);
    int m = (l + r) >> 1;
    if (L <= m) update(op , L , R , lson);
    else if (op == 'I' || op == 'C') {
        XOR[rt<<1] = cover[rt<<1] = 0;
    }
    if (m < R) update(op , L , R , rson);
    else if (op == 'I' || op == 'C') {
        XOR[rt<<1|1] = cover[rt<<1|1] = 0;
    }
}
void query(int l,int r,int rt) {
    if (cover[rt] == 1) {
        for (int it = l ; it <= r ; it ++) {
            hash1[it] = true;
        }
        return ;
    } else if (cover[rt] == 0) return ;
    if (l == r) return ;
    PushDown(rt);
    int m = (l + r) >> 1;
    query(lson);
    query(rson);
}
int main() {
    cover[1] = XOR[1] = 0;
    char op , l , r;
    int a , b;
    while ( ~scanf("%c %c%d,%d%c
",&op , &l , &a , &b , &r) ) {
        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);
    }
    query(0 , maxn , 1);
    bool flag = false;
    int s = -1 , e;
    for (int i = 0 ; i <= maxn ; i ++) {
        if (hash1[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

  思考: 哎, still have a long way to go 啊..........

原文地址:https://www.cnblogs.com/FriskyPuppy/p/7324785.html