题目大意
需要兹瓷集合合并与删去集合内最小值。
可并堆
还能说什么呢,裸的……
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=1000000+10;
int fa[maxn],dis[maxn],left[maxn],right[maxn],a[maxn],root[maxn];
bool bz[maxn];
int i,j,k,l,t,n,m;
char ch;
char get(){
char ch=getchar();
while (ch!='M'&&ch!='K') ch=getchar();
return ch;
}
int read(){
int x=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
int getfa(int x){
return fa[x]?fa[x]=getfa(fa[x]):x;
}
int merge(int x,int y){
if (!x||!y) return x+y;
if (a[x]>a[y]) swap(x,y);
right[x]=merge(right[x],y);
if (dis[left[x]]<dis[right[x]]) swap(left[x],right[x]);
dis[x]=dis[right[x]]+1;
return x;
}
int deletemin(int x){
return merge(left[x],right[x]);
}
int main(){
n=read();
fo(i,1,n) a[i]=read(),root[i]=i;
m=read();
fo(i,1,m){
ch=get();
if (ch=='M'){
j=read();k=read();
if (bz[j]||bz[k]) continue;
j=getfa(j);
k=getfa(k);
if (j==k) continue;
fa[j]=k;
root[k]=merge(root[j],root[k]);
}
else{
j=read();
if (bz[j]) printf("0\n");
else{
j=getfa(j);
printf("%d\n",a[root[j]]);
bz[root[j]]=1;
root[j]=deletemin(root[j]);
}
}
}
}