题意:四种集合的操作,对应区间的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 ", &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; }