# 罗马游戏

1. M i j
2. K i

5

100 90 66 99 10

7

M 1 5

K 1

K 1

M 2 3

M 3 4

K 5

K 4

### Sample Output

10

100

0

66

stl的堆不是可并堆。。。所以我写了个左偏堆（因为好写。。。。） 这个板子有点窒息。。。。注意如果你的堆很小，有个儿子就是0，那么你的fa[0] 会被改，然后你以后可能也会用到fa[0]，你就凉凉。。。。
`c++

# include<bits/stdc++.h>

using namespace std;
const int maxn = 1e6 + 10, L = 0, R = 1;
struct lpl{
int data, dis, son[2];
}node[maxn];
int n, m, fa[maxn];
bool flag[maxn];

namespace Left_Partial_Tree{
int find(int t){return (t == fa[t]) ? (t) : (fa[t] = find(fa[t]));}
int merge(int A, int B){
if(A * B == 0) return A + B;
if(node[A].data > node[B].data) swap(A, B);
node[A].son[R] = merge(node[A].son[R], B);
if(node[node[A].son[L]].dis < node[node[A].son[R]].dis) swap(node[A].son[L], node[A].son[R]);
node[A].dis = node[node[A].son[R]].dis + 1;
return A;
}
inline void pop(int t){
t = find(t); int A = node[t].son[L], B = node[t].son[R];
int tmp = merge(A, B); A = find(A), B = find(B);
fa[A] = tmp; fa[B] = tmp; fa[tmp] = tmp;
node[t].son[L] = node[t].son[R] = node[t].data = node[t].dis = 0;
}
}

int main()
{
scanf("%d", &n); node[0].dis = -1;
for(int i = 1; i <= n; ++i){scanf("%d", &node[i].data); fa[i] = i;}
scanf("%d", &m); char s[21]; int x, y;
while(m--){
scanf("%s", s + 1);
if(s[1] == 'M'){
scanf("%d%d", &x, &y); if(flag[x] || flag[y]) continue;
int A = Left_Partial_Tree::find(x), B = Left_Partial_Tree::find(y);
if(A == B) continue;
int F = Left_Partial_Tree::merge(A, B);
fa[A] = F; fa[B] = F;
}
else{
scanf("%d", &x); if(flag[x]){printf("0\n"); continue;}
int A = Left_Partial_Tree::find(x);
printf("%d\n", node[A].data); Left_Partial_Tree::pop(A); flag[A] = true;
}
fa[0] = 0;
}
return 0;
}

posted @ 2018-07-25 17:04  沛霖  阅读(134)  评论(0编辑  收藏  举报