BZOJ1455罗马游戏
左偏树裸题
(搞板子搞到绝望x
//罗马游戏 #include <bits/stdc++.h> using namespace std; const int N = 1000050; int val[N], l[N], r[N], d[N], fa[N]; int x, y, n, m; char ord; // 合并以 x, y为根的堆,返回合并后的堆顶 int merge(int x, int y) { if(!x||!y) return x|y; // 键值小的作为堆顶 if (val[x] > val[y]) swap(x, y); r[x] = merge(r[x], y); // 维护左偏性质 if (d[r[x]] > d[l[x]]) swap(l[x], r[x]); // 重新计算距离 d[x] = d[r[x]] + 1; return x; } int find(int x) { if(fa[x] == x) return x; else return fa[x] = find(fa[x]); } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &val[i]); fa[i] = i; } scanf("%d", &m); for (int i = 1; i <= m; i++) { cin >> ord; if (ord == 'M') { scanf("%d%d", &x, &y); if (val[x] < 0 || val[y] < 0) continue; x = find(x), y = find(y); if (x != y) { int t = merge(x, y); fa[x] = fa[y] = t; } } else { scanf("%d", &x); if (val[x] < 0) { puts("0"); continue; } x = find(x); printf("%d\n", val[x]); val[x] = -1; fa[x] = merge(l[x], r[x]); fa[fa[x]] = fa[x]; } } return 0; }
满堂花醉三千客,一剑霜寒十四州