题面在这里
题目大意:
有
n
个物品排成一行。三种操作:
D x 表示将第x 个物品摧毁;- R 表示将上一个物品回复;
Q x 表示查询x 所在连通块的个数。做法:
平衡树中保存摧毁的物品编号。
查询时只需查询 x 的前驱pre 后继 nxt ,然后输出 nxt−pre−1 即可。/************************************************************* Problem: poj 2892 Tunnel Warfare User: fengyuan Language: C++ Result: Accepted Time: 266 ms Memory: 1.1 MB Submit_Time: 2017-12-09 00:12:45 *************************************************************/ #include<cstdio> #include<cstring> #define rep(i, x, y) for (int i = (x); i <= (y); i ++) #define down(i, x, y) for (int i = (x); i >= (y); i --) #define mid ((l+r)/2) #define lc (o<<1) #define rc (o<<1|1) #define pb push_back #define mp make_pair #define PII pair<int, int> #define F first #define S second #define B begin() #define E end() using namespace std; typedef long long LL; //head const int N = 50010, M = 1500010; int n, m, top, rt, tot; char opt[5]; bool vis[N]; int st[N]; int fa[M], ch[M][2], data[M]; inline void clear(int x) { fa[x] = ch[x][0] = ch[x][1] = data[x] = 0; } inline void rot(int x) { int y = fa[x], z = fa[y]; int f = ch[y][1] == x; ch[y][f] = ch[x][f^1]; if (ch[x][f^1]) fa[ch[x][f^1]] = y; fa[x] = z; if (z) ch[z][ch[z][1] == y] = x; fa[y] = x; ch[x][f^1] = y; } inline void splay(int x, int top) { while (fa[x] != top){ int y = fa[x], z = fa[y]; if (z != top) rot(((ch[z][0] == y) == (ch[y][0] == x)) ? y : x); rot(x); } if (!top) rt = x; } inline int find(int v) { int x = rt; while (x){ if (data[x] == v){ splay(x, 0); return x; } x = ch[x][v > data[x]]; } } inline int pre(int x) { x = ch[x][0]; while (ch[x][1]) x = ch[x][1]; return x; } inline int nxt(int x) { x = ch[x][1]; while (ch[x][0]) x = ch[x][0]; return x; } inline void insert(int v) { int x = rt; if (!rt){ rt = x = ++ tot; data[x] = v; fa[x] = ch[x][0] = ch[x][1] = 0; return; } while (x){ int &y = ch[x][v > data[x]]; if (!y){ y = ++ tot; data[y] = v; fa[y] = x; ch[y][0] = ch[y][1] = 0; x = y; break; } x = y; } splay(x, 0); } inline void del(int v) { int x = find(v); if (!ch[x][0] && !ch[x][1]){ clear(x); rt = 0; return; } if (!ch[x][0]){ rt = ch[x][1]; fa[rt] = 0; return; } if (!ch[x][1]){ rt = ch[x][0]; fa[rt] = 0; return; } int p = pre(x), rtt = rt; splay(p, 0); ch[rt][1] = ch[rtt][1]; fa[ch[rtt][1]] = rt; clear(rtt); } int main() { scanf("%d%d", &n, &m); insert(0); insert(n+1); while (m --){ scanf("%s", opt); int x; if (opt[0] == 'D'){ scanf("%d", &x); vis[x] = 1; st[++ top] = x; insert(x); } else if (opt[0] == 'R'){ del(st[top]); vis[st[top --]] = 0; } else { scanf("%d", &x); if (vis[x]){ puts("0"); continue; } insert(x); printf("%d\n", data[nxt(rt)] - data[pre(rt)] - 1); del(x); } } return 0; }