• 待解决的问题 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 啊..........

  • 相关阅读:
    高斯消元
    UVa12103
    UVa10294
    UVa11762
    牛客网算法工程师能力评估
    华为研发工程师编程题
    网易2017春招笔试真题编程题集合
    2017网易有道内推编程题
    2017网易雷火实习生招聘编程题
    数组---面试知识点整理
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7324785.html
Copyright © 2020-2023  润新知