poj 3225 Help with Intervals(线段树进阶,处理区间,拆点)
来源:互联网 发布:c语言求真值表 编辑:程序博客网 时间:2024/05/23 12:06
题意:
求区间的交,并,补,对称差。。
思路:
为了表示开闭区间,用偶数表示闭区间端点,奇数表示开区间的。
[2,3) -> 4, 5
(3, 7) -> 7, 13
集合操作可以分解为两种,set和xor。。
先实现这两种操作,再讨论情况。。
const int Maxn = 65550*2;#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)|1)struct node { int cover, x;};node a[Maxn*4+5];void xor_helper(int o) { if (a[o].cover == -1) { a[o].x ^= 1; } else { a[o].cover ^= 1; }}// 两种标记不会同时存在void push_down(int o) { int lc = lson(o), rc = rson(o); if (a[o].cover != -1) { a[lc].cover = a[rc].cover = a[o].cover; a[lc].x = a[rc].x = 0; a[o].cover = -1; } if (a[o].x) { xor_helper(lc);xor_helper(rc); a[o].x = 0; }}void seg_update_cover(int L, int R, int o, int qL, int qR, int v) { if (qL <= L && R <= qR) { a[o].cover = v; a[o].x = 0; return; } push_down(o); int lc = lson(o), rc = rson(o), mid = (L+R)>>1; if (qL <= mid) seg_update_cover(L, mid, lc, qL, qR, v); if (qR > mid) seg_update_cover(mid+1, R, rc, qL, qR, v);}void seg_update_xor(int L, int R, int o, int qL, int qR) { if (qL <= L && R <= qR) { xor_helper(o);return; } push_down(o); int lc = lson(o), rc = rson(o), mid = (L+R)>>1; if (qL <= mid) seg_update_xor(L, mid, lc, qL, qR); if (qR > mid) seg_update_xor(mid+1, R, rc, qL, qR);}// query and markint mark[Maxn+5];void seg_query(int L, int R, int o) { if (a[o].cover == 1) {rep(i, L-1, R-1) mark[i] = 1;return;} if (!a[o].cover) return; push_down(o); int lc = lson(o), rc = rson(o), mid = (L+R)>>1; seg_query(L, mid, lc);seg_query(mid+1, R, rc);}void seg_build(int L, int R, int o) { a[o] = (node) {0, 0}; if (L < R) { int lc = lson(o), rc = rson(o), mid = (L+R)>>1; seg_build(L, mid, lc);seg_build(mid+1, R, rc); }}// debugvoid seg_print(int L, int R, int o, int num) { if (a[o].cover == 1) {printf("(%d %d)\n", L-1, R-1);return;} if (a[o].cover == 0)return; push_down(o); int lc = lson(o), rc = rson(o), mid = (L+R)>>1; seg_print(L, mid, lc, num+1);seg_print(mid+1, R, rc, num+1);}void ask() { int n = Maxn; memset(mark, 0, sizeof(mark)); seg_query(1, n, 1); vector<pair<int, int> > ans; int s = -1, e = -1; for(int i=0;i<Maxn;++i) { if (mark[i]) { if (s == -1) s = i; e = i; } else { if (s != -1) { ans.push_back(make_pair(s, e)); s = -1; } } } if (ans.empty()) {printf("empty set\n");return;} for (int i=0;i<ans.size();++i) { int a = ans[i].first, b = ans[i].second; char lhs = '[', rhs = ']'; if (ans[i].first & 1) { lhs = '('; --a; } if (ans[i].second & 1) { rhs = ')'; ++b; } printf("%c%d,%d%c", lhs, a/2, b/2, rhs); printf("%c", i == ans.size()-1 ? '\n':' '); }}int main() {#ifndef ONLINE_JUDGE freopen("input.in", "r", stdin);#endif // ONLINE_JUDGE char a, b, c;int x, y; int n = Maxn; seg_build(1, n, 1); while (scanf("%c %c%d,%d%c\n", &a, &b, &x, &y, &c) != EOF) { x *= 2;y *= 2; if (b == '(') ++x;if (c == ')') --y; x += 1;y += 1; // 因为最小为0,所以对应到线段树上的区间时+1 //printf("%c %d %d\n", a, x-1, y-1); if (x > y) continue; if (a == 'U') { seg_update_cover(1, n, 1, x, y, 1); } else if (a == 'I') { if (x - 1 >= 1) seg_update_cover(1, n, 1, 1, x-1, 0); seg_update_cover(1, n, 1, y+1, Maxn, 0); } else if (a == 'D') { seg_update_cover(1, n, 1, x, y, 0); } else if (a == 'C') { if (x - 1 >= 1) seg_update_cover(1, n, 1, 1, x-1, 0); seg_update_cover(1, n, 1, y+1, Maxn, 0); seg_update_xor(1, n, 1, x, y); } else if (a == 'S') { seg_update_xor(1, n, 1, x, y); } //seg_print(1, n, 1, 0); //ask(); } ask(); return 0;}
0 0
- poj 3225 Help with Intervals(线段树进阶,处理区间,拆点)
- POJ 3225 Help with Intervals (线段树,区间更新)
- poj 3225 Help with Intervals(线段树区间更新)
- poj 3225 Help with Intervals(线段树+区间更新)
- POJ 3225 Help with Intervals --线段树区间操作
- POJ 3255 Help with Intervals (线段树区间更新)
- POJ 3225 Help with Intervals 线段树
- POJ 3225 Help with Intervals 线段树
- POJ 3225 Help with Intervals 线段树
- poj 3225 Help with Intervals[线段树]
- POJ-3225 Help with Intervals 线段树
- POJ 3225 Help with Intervals (线段树)
- poj 3225 Help with Intervals (线段树)
- poj 3225 Help with Intervals(线段树)
- POJ 3225 Help with Intervals 线段树
- POJ 3225 Help with Intervals 【线段树】
- poj 3225 线段树区间更新,区间询问 Help with Intervals
- POJ 3225 Help with Intervals(线段树:区间置0/1,区间异或)
- 鼠标移动上去后,行变色
- VS2010中语句块代码的折叠显示
- 个推使用总结
- Oracle 11g 透明网关
- Fliptile POJ3279 二进制压缩枚举 解题报告
- poj 3225 Help with Intervals(线段树进阶,处理区间,拆点)
- 存一些数学用的模板
- 多应用中EditText中可以插入图片,并且图片可以响应点击事件来进行相关操作。
- 十九、C++程序设计必知:生存期
- 串,包括KMP算法(C/C++)
- 动画-IOS开发
- shell脚本使用
- 80端口被占用了怎么办?
- Deep Learning 学习资料