线段树(区间操作) POJ 3325 Help with Intervals
2016-03-24 20:05
387 查看
题目传送门
题意:四种集合的操作,对应区间的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判奇偶得
题意:四种集合的操作,对应区间的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 ; 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; }
相关文章推荐
- linux下的open函数中的mode问题
- CALayer使用(1)
- iOS缓存清理
- 关于“模仿”和“创新”
- kindeditor使用
- MyEclipse------如何连接MySQL
- 【bzoj3160】万径人踪灭 FFT+manacher
- 《编写高质量代码:改善Objective-C程序的61个建议》
- Struts2中的相对路径与绝对路径
- FragmentPagerAdapter与FragmentStatePagerAdapter
- 【HPU】[1732]序列的区间操作
- 《谈学单片机有前途还是嵌入式系统有前途》一文吴坚鸿回复整理
- linux用户操作
- shell 脚本编写一个用户名,密码,编号的test.txt文件供数据库测试使用
- 《谈学单片机有前途还是嵌入式系统有前途》一文吴坚鸿回复整理
- 《谈学单片机有前途还是嵌入式系统有前途》一文吴坚鸿回复整理
- 《世界是数字的》读后感
- 奇闻轶事
- iOS之表格数据批量删除(系统样式)
- String的解析