BZOJ-1455 罗马游戏
同样是道可并堆题。配对堆模版题。
#include <cctype> #include <algorithm> #include <cstring> #include <cstdlib> #include <cstdio> #include <iostream> #define rep(i, l, r) for(int i=l; i<=r; i++) #define clr(x, c) memset(x, c, sizeof(x)) #define ll long long #define maxn 1000009 using namespace std; inline int read() { int x=0; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0', ch=getchar(); return x; } struct node{int l, r, ch; node(){l=r=ch;}} h[maxn]; int n, m, k[maxn], roof[maxn]; bool die[maxn]; inline int Join(int v, int u) { if (v==u) return v; if (k[v]<k[u]) swap(v, u); h[v].l=u, h[v].r=h[u].ch, h[h[u].ch].l=v, h[u].ch=v; roof[v]=u; return u; } int Top(int v){return roof[v]==v ? v : Top(roof[v]);} int st[maxn], top; inline int Kill(int v) { die[v]=true; int ans=k[v]; if (h[v].ch) { top=0; int t=h[v].ch; while (t) if (h[t].r) { int k=h[h[t].r].r; int v=h[t].r; h[v].l=h[v].r=h[t].l=h[t].r=0; roof[t]=t, roof[v]=v; st[++top]=Join(t, v); t=k; } else { st[++top]=t; h[t].l=h[t].r=0; roof[t]=t; break; } t=st[top]; rep(i, 1, top-1) t=Join(t, st[i]); } return ans; } char s[5]; int main() { n=read(); rep(i, 1, n) k[i]=read(), roof[i]=i; m=read(); rep(i, 1, m) { scanf("%s", s); if (s[0]=='M') {int v=read(), u=read(); if (!die[v] && !die[u]) Join(Top(v), Top(u));} else {int v=read(); if (!die[v]) printf("%d\n", Kill(Top(v))); else printf("0\n");} } return 0; }