程序员人生 网站导航

poj 3225 Help with Intervals(线段树)

栏目:互联网时间:2014-10-02 08:00:00

题目链接:poj 3225 Help with Intervals

题目大意:模拟集合操作,输出最终的集合。

解题思路:线段树。

  • U l r:[l,r]区间置为1
  • I l r:[0,l),(r,maxn]置为0
  • D l r:[l,r]区间置为0
  • C l r:[0,l),(r,maxn]置为0,[l,r]区间取逆
  • S l r:[l,r]区间取逆。

然后基本水水的线段树,注意一下区间开和闭。

#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 65535 * 2; #define lson(x) ((x)<<1) #define rson(x) (((x)<<1)+1) int lc[maxn * 4], rc[maxn * 4], set[maxn * 4], filp[maxn * 4]; inline void splay(int u) { filp[u] ^= 1; if (filp[u] && set[u] != -1) { filp[u] = 0; set[u] ^= 1; } } inline void maintain(int u, int v) { set[u] = v; filp[u] = 0; } inline void pushdown (int u) { if (set[u] != -1) { maintain(lson(u), set[u]); maintain(rson(u), set[u]); set[u] = -1; } if (filp[u]) { splay(lson(u)); splay(rson(u)); filp[u] = 0; } } void build (int u, int l, int r) { lc[u] = l; rc[u] = r; maintain(u, -1); if (l == r) { maintain(u, 0); return; } int mid = (l + r) / 2; build (lson(u), l, mid); build (rson(u), mid + 1, r); } void modify (int u, int l, int r, int v) { if (l > r) return; if (l <= lc[u] && rc[u] <= r) { maintain(u, v); return; } pushdown(u); int mid = (lc[u] + rc[u]) / 2; if (l <= mid) modify(lson(u), l, r, v); if (r > mid) modify(rson(u), l, r, v); } void change (int u, int l, int r) { if (l > r) return; if (l <= lc[u] && rc[u] <= r) { splay(u); return; } pushdown(u); int mid = (lc[u] + rc[u]) / 2; if (l <= mid) change(lson(u), l, r); if (r > mid) change(rson(u), l, r); } int query (int u, int x) { if (lc[u] == x && x == rc[u]) return set[u]; pushdown(u); int mid = (lc[u] + rc[u]) / 2; if (x <= mid) return query(lson(u), x); else return query(rson(u), x); } int L, R; char op, LP, RP; inline void put (int left, int right) { if (left&1) printf("(%d,", left/2); else printf("[%d,", left/2); if (right&1) printf("%d)", (right + 1) / 2); else printf("%d]", right / 2); } int main () { build (1, 0, maxn); while (~scanf("%c%*c%c%d,%d%c%*c", &op, &LP, &L, &R, &RP)) { L *= 2; R *= 2; if (LP == '(') L++; if (RP == ')') R--; if (op == 'U') { modify(1, L, R, 1); } else if (op == 'I') { modify(1, 0, L - 1, 0); modify(1, R + 1, maxn, 0); } else if (op == 'D') { modify(1, L, R, 0); } else if (op == 'C') { change(1, L, R); modify(1, 0, L - 1, 0); modify(1, R + 1, maxn, 0); } else if (op == 'S') change(1, L, R); } bool flag = false; int c = 0, t; for (int i = 0; i <= maxn; i++) { int s = query(1, i); if (s && !flag) { t = i; flag = true; } else if (!s && flag) { if (c++) printf(" "); put(t, i-1); flag = false; } } if (c == 0) printf("empty set "); else printf(" "); return 0; }
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐