线段树(区间操作) POJ 3325 Help with Intervals

 

题目传送门

题意:四种集合的操作,对应区间的01,问最后存在集合存在的区间。

分析:U T [l, r]填充1; I T [0, l), (r, N]填充0; D T [l, r]填充0; C T[0, l), (r, N]填充0并且[l, r]xor; S T [l, r]xor

线段树结点两个属性,cover[o]: 该区间是否填充(1, 0, -1),_xor[o]: 该区间是否异或反转(1, 0)。最后(和[的区别可以原数*2判奇偶得

#include <cstdio>
#include <cstring>
#include <algorithm>

#define lson l, mid, o << 1
#define rson mid + 1, r, o << 1 | 1
typedef long long ll; 
const int N = 2 * 65535 + 5;
bool vis[N];
int cover[N<<2], _xor[N<<2];

void Xor(int o) {
    if (cover[o] != -1) {
        cover[o] ^= 1;
    } else {
        _xor[o] ^= 1;
    }
}
void push_down(int o) {
    if (cover[o] != -1) {
        cover[o<<1] = cover[o<<1|1] = cover[o];
        _xor[o<<1] = _xor[o<<1|1] = 0;
        cover[o] = -1;
    }
    if (_xor[o]) {
        Xor (o<<1);
        Xor (o<<1|1);
        _xor[o] = 0;
    }
}
void updata(int ql, int qr, char op, int l, int r, int o) {
    if (ql <= l && r <= qr) {
        if (op == 'U') {
            cover[o] = 1;
            _xor[o] = 0;
        } else if (op == 'D') {
            cover[o] = _xor[o] = 0;
        } else if (op == 'C' || op == 'S') {
            Xor (o);
        }
        return ;
    }
    push_down (o);
    int mid = l + r >> 1;
    if (ql <= mid) {
        updata (ql, qr, op, lson);
    } else if (op == 'I' || op == 'C') {
        cover[o<<1] = _xor[o<<1] = 0;
    }
    if (qr > mid) {
        updata (ql, qr, op, rson);
    } else if (op == 'I' || op == 'C') {
        cover[o<<1|1] = _xor[o<<1|1] = 0;
    }
}
void query(int l, int r, int o) {
    if (cover[o] == 1) {
        for (int i=l; i<=r; ++i) {
            vis[i] = true;
        }
        return ;
    } else if (cover[o] == 0) {
        return ;
    }
    if (l == r) {
        return ;
    }
    push_down (o);
    int mid = l + r >> 1;
    query (lson);
    query (rson);
}

int main() {
    char op, l, r; int a, b;
    int n = N - 5;
    cover[1] = cover[1] = 0;
    while (~scanf ("%c %c%d,%d%c\n", &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 {
            updata (a, b, op, 0, n, 1);
        }
    }
    memset (vis, false, sizeof (vis));
    query (0, n, 1);
    bool flag = false;
    int s = -1, e = 0;
    for (int i=0; i<=n; ++i) {
        if (vis[i]) {
            if (s == -1) {
                s = i;
            }
            e = i;
        } else {
            if (s != -1) {
                if (flag) putchar (' ');
                flag = true;
                printf ("%c%d,%d%c", s&1 ? '(' : '[', s>>1, (e+1)>>1, e&1 ? ')' : ']');
                s = -1;
            }
        }
    }
    if (flag) {
        puts ("");
    } else {
        puts ("empty set");
    }

    return 0;
}

  

 

转载于:https://www.cnblogs.com/Running-Time/p/5316956.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值