【链接】
bzoj2733
【解题报告】
好像是平衡树裸题吧,然后splay启发式合并码掉了。
#include
#include
using namespace std;
const int maxn=100005;
int n,m,Q,w[maxn],c[maxn],fa[maxn];
struct Splay
{
Splay* son[2];
int x,s,p;
Splay (int a=0,int b=0,Splay* t=NULL) {x=a; p=b; s=1; son[0]=son[1]=t;}
int Cmp1(int k) {if (k==p) return -1; if (kreturn 0; return 1;}
int Cmp2(int &k) {int t=son[0]->s+1; if (k==t) return -1; if (kreturn 0; k-=t; return 1;}
void Pushup() {s=son[0]->s+son[1]->s+1;}
}tem[maxn],*Null=tem,*len=Null,*ro[maxn];
inline char nc()
{
static char buf[100000],*l,*r;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF; return *l++;
}
inline int Read()
{
int res=0,f=1; char ch=nc(),cc=ch;
while (ch<'0'||ch>'9') cc=ch,ch=nc();
if (cc=='-') f=-1;
while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=nc();
return res*f;
}
void init_Null() {Null->s=0; Null->son[0]=Null->son[1]=Null;}
void Rotate(Splay* &k,int d)
{
Splay* t=k->son[d]; k->son[d]=t->son[d^1]; t->son[d^1]=k;
k->Pushup(); t->Pushup(); k=t;
}
void Splay_Work(Splay* &k,int x)
{
int d1=k->Cmp1(x);
if (d1>-1)
{
Splay* p=k->son[d1];
int d2=p->Cmp1(x);
if (d2>-1)
{
Splay_Work(p->son[d2],x);
if (d1==d2) Rotate(k,d1),Rotate(k,d1); else Rotate(k->son[d1],d2),Rotate(k,d1);
} else Rotate(k,d1);
}
}
int Kth(Splay* &k,int x)
{
int d=k->Cmp2(x);
if (d<0) return k->x;
else return Kth(k->son[d],x);
}
int Getfa(int x)
{
if (x==fa[x]) return x;
fa[x]=Getfa(fa[x]);
return fa[x];
}
void Insert(Splay* &k,int x,int p)
{
if (k==Null) k=new Splay(x,p,Null);
else Insert(k->son[p>k->p],x,p);
k->Pushup();
}
void Delete(Splay* k)
{
if (k==Null) return;
Delete(k->son[0]); c[++c[0]]=k->x; Delete(k->son[1]);
delete k;
}
void Merga(int x,int y)
{
x=Getfa(x); y=Getfa(y);
if (x==y) return;
Splay *p1=ro[x],*p2=ro[y];
if (p1->ss) swap(p1,p2);
c[0]=0; Delete(p2);
for (int i=1; i<=c[0]; i++) Insert(p1,c[i],w[c[i]]),Splay_Work(p1,w[c[i]]);
ro[fa[x]=y]=p1;
}
int main()
{
freopen("2733.in","r",stdin);
freopen("2733.out","w",stdout);
n=Read(); m=Read(); init_Null();
for (int i=1,x; i<=n; i++) w[i]=Read(),fa[i]=i,ro[i]=new Splay(i,w[i],Null);
for (int i=1,x,y; i<=m; i++) x=Read(),y=Read(),Merga(x,y);
Q=Read();
while(Q--)
{
char ch=nc();
while (ch!='Q'&&ch!='B') ch=nc();
int x=Read(),y=Read();
if (ch=='Q') {int t=Getfa(x); if (ro[t]->sprintf("-1\n"); else {int v=Kth(ro[t],y); Splay_Work(ro[t],w[v]); printf("%d\n",v);}}
else Merga(x,y);
}
return 0;
}