题目:
题解:
求解集合内第k大的话是splay的基本操作
那么维护连通性用并查集,然后就是个splay启发式合并的裸题了。
splay启发式合并,按照splay的后序遍历进行合并,不然如果你从头就开始合并父子关系就混乱了
时间复杂度是
O(nlog2n)
O
(
n
l
o
g
2
n
)
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N=100005;
int ch[N][2],f[N],fa[N],size[N],root[N],key[N];
int findfa(int x){if (fa[x]!=x) fa[x]=findfa(fa[x]);return fa[x];}
int get(int x){return ch[f[x]][1]==x;}
void updata(int now)
{
size[now]=1;
if (ch[now][0]) size[now]+=size[ch[now][0]];
if (ch[now][1]) size[now]+=size[ch[now][1]];
}
void rotate(int x)
{
int old=f[x],oldf=f[old],which=get(x);
f[x]=oldf; if (oldf) ch[oldf][get(old)]=x;
ch[old][which]=ch[x][which^1]; f[ch[x][which^1]]=old;
ch[x][which^1]=old; f[old]=x;
updata(old);
updata(x);
}
void splay(int x,int id)
{
for (;f[x];rotate(x))
if (f[f[x]]) rotate(get(x)==get(f[x])?f[x]:x);
root[id]=x;
}
int find(int x,int now)//找排名为x的编号
{
while (1)
{
if (ch[now][0] && size[ch[now][0]]>=x) now=ch[now][0];
else
{
x-=size[ch[now][0]]+1;
if (x<=0) return now;
now=ch[now][1];
}
}
}
void insert(int sz,int x,int to)
{
int now=root[to],fa=0;
while (1)
{
fa=now; now=ch[now][key[now]<x];
if (!now)
{
f[sz]=fa; ch[fa][key[fa]<x]=sz;
size[sz]=1;
updata(fa);
splay(sz,to);return;
}
}
}
void merge(int now,int to)
{
if (ch[now][0]) merge(ch[now][0],to);
if (ch[now][1]) merge(ch[now][1],to);
insert(now,key[now],to);
}
//key f ch[0] ch[1] size
int main()
{
int n,m,q;scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&key[i]),fa[i]=root[i]=i,size[i]=1;
for (int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
int xa,ya;xa=findfa(x);ya=findfa(y);
if (xa==ya) continue;
if (size[root[xa]]>size[root[ya]]) swap(x,y),swap(xa,ya);
merge(root[xa],ya); fa[xa]=ya;
}
scanf("%d",&q);
while (q--)
{
char st[5]; int x,y;scanf("%s",st);
scanf("%d%d",&x,&y);
if (st[0]=='Q')
{
x=findfa(x);
if (y>size[root[x]]) printf("-1\n");
else printf("%d\n",find(y,root[x]));
}else
{
int xa,ya;xa=findfa(x);ya=findfa(y);
if (xa==ya) continue;
if (size[root[xa]]>size[root[ya]]) swap(x,y),swap(xa,ya);
merge(root[xa],ya); fa[xa]=ya;
}
}
}