用启发式合并splay维护,复杂度是 O(nlogn) 。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1000010;
int rd()
{
int x=0;
char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
char rdc()
{
char c=getchar();
while (c<'A'||c>'Z') c=getchar();
return c;
}
int fa[maxn],son[maxn][2],size[maxn],val[maxn],n,q;
void pause()
{
}
void rot(int u,int fl)
{
int v=son[u][fl],x=son[v][fl^1],f=fa[u];
if (f) son[f][son[f][1]==u]=v;
fa[v]=f;
son[v][fl^1]=u;
fa[u]=v;
son[u][fl]=x;
if (x) fa[x]=u;
size[u]=size[son[u][0]]+size[son[u][1]]+1;
size[v]=size[son[v][0]]+size[son[v][1]]+1;
}
void splay(int u)
{
int x,fx,y,fy;
while (fa[u])
{
x=fa[u];
fx=son[x][1]==u;
if (!fa[x]) rot(x,fx);
else
{
y=fa[x];
fy=son[y][1]==x;
if (fx==fy) rot(y,fy),rot(x,fx);
else rot(x,fx),rot(y,fy);
}
}
}
void ins(int u,int v)
{
size[u]++;
if (val[v]<val[u])
{
if (son[u][0]) ins(son[u][0],v);
else
{
son[u][0]=v;
fa[v]=u;
}
}
else
{
if (son[u][1]) ins(son[u][1],v);
else
{
son[u][1]=v;
fa[v]=u;
}
}
}
int qry(int u,int k)
{
//printf("%d,%d,%d\n",u,size[u],k);
if (k<=size[son[u][0]]) return qry(son[u][0],k);
if (k==size[son[u][0]]+1) return u;
return qry(son[u][1],k-size[son[u][0]]-1);
}
void Insert(int r,int u)
{
if (son[u][0]) Insert(r,son[u][0]);
if (son[u][1]) Insert(r,son[u][1]);
son[u][0]=son[u][1]=0;
size[u]=1;
ins(r,u);
splay(u);
}
void Join(int u,int v)
{
if (!u||!v) return;
splay(u);
splay(v);
if (fa[u]) return;
if (size[u]<size[v]) swap(u,v);
Insert(u,v);
}
int Query(int u,int k)
{
splay(u);
if (size[u]<k) return -1;
int v=qry(u,k);
splay(v);
return v;
}
int main()
{
//freopen("d.in","r",stdin);
//freopen("bzoj_2733.in","r",stdin);
//freopen("bzoj_2733.out","w",stdout);
int u,v;
char c;
n=rd();
q=rd();
for (int i=1;i<=n;i++) val[i]=rd(),size[i]=1;
while (q--)
{
u=rd();
v=rd();
//if (!q) pause();
Join(u,v);
//if (size[0]) pause();
}
q=rd();
while (q--)
{
c=rdc();
u=rd();
v=rd();
if (c=='B') Join(u,v);
else printf("%d\n",Query(u,v));
}
}