裸可并堆
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
char c;
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
struct Node
{
Node *lc,*rc;
int Da,no;
Node(){lc=rc=NULL;}
}*T[1000001];
Node *Merge(Node *a,Node *b)
{
if(a==NULL)return b;
if(b==NULL)return a;
if(a->Da>b->Da)
{
if(rand()&1)
b->lc=Merge(a,b->lc);
else b->rc=Merge(a,b->rc);
return b;
}
else if(rand()&1)
a->lc=Merge(b,a->lc);
else a->rc=Merge(b,a->rc);
return a;
}
bool del[1000001];
int Top(Node *A){return A->Da;}
void Pop(Node *&A){del[A->no]=true;A=Merge(A->lc,A->rc);}
int f[1000001];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
int main()
{
int n,m;
read(n);
for(int i=1;i<=n;i++)f[i]=i,T[i]=new Node,read(T[i]->Da),del[i]=false,T[i]->no=i;
read(m);
for(int i=1;i<=m;i++)
{
do c=getchar();while(c!='M'&&c!='K');
if(c=='M')
{
int x,y;
read(x),read(y);
if(del[x]||del[y])continue;
x=find(x),y=find(y);
if(x==y)continue;
f[x]=y;
T[y]=Merge(T[y],T[x]);
}
else{int k;read(k);if(del[k]){puts("0");continue;}
k=find(k);printf("%d\n",Top(T[k]));Pop(T[k]);}
}
return 0;
}