bzoj2733: [HNOI2012]永无乡

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2733

思路:splay裸题,没啥好说的...用来练练手

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ls ch[p][0]
#define rs ch[p][1]
const int maxn=100010;
using namespace std;
int f[maxn],n,m,Q,v[maxn],q[maxn],head,tail;char op[5];
int getfa(int x){return f[x]==x?x:f[x]=getfa(f[x]);}

struct Tsplay{
	int fa[maxn],ch[maxn][2],root,v[maxn],siz[maxn];
	void update(int p){siz[p]=siz[ls]+siz[rs]+1;}
	int which(int x){return ch[fa[x]][1]==x;}
	void rotate(int x){
		int y=fa[x],z=fa[y],nx=which(x),ny=which(y);
		ch[y][nx]=ch[x][!nx],fa[ch[x][!nx]]=y;
		fa[y]=x,ch[x][!nx]=y;
		fa[x]=z;if (z) ch[z][ny]=x;update(y);
	}
	void splay(int x,int goal){
		while (fa[x]!=goal){
			int y=fa[x],z=fa[y];
			if (z==goal) rotate(x);
			else if (which(x)==which(y)) rotate(y),rotate(x);
			else rotate(x),rotate(x);
		}
		if (!goal) root=x;update(x);
	}
	void insert(int a){
		int p=root;
		while (1){
			if (v[a]<v[p]){
				if (!ls) return ls=a,fa[a]=p,splay(a,0),void();
				else p=ls;
			}
			else{
				if (!rs) return rs=a,fa[a]=p,splay(a,0),void();
				else p=rs;
			}
		}
	}
	void merge(int x,int y){
		if (siz[x]<siz[y]) swap(x,y);
		f[y]=x,root=x;
		head=0,q[tail=1]=y;
		while (head!=tail){
			int p=q[++head];
			if (ls) q[++tail]=ls;
			if (rs) q[++tail]=rs;
			ls=rs=0,siz[p]=1,insert(p);
		}
		splay(x,0);
	}
	int findrank(int a,int k){
		if (k>siz[a]) return -1;
		int p=root;
		while (1){
			if (siz[ls]>=k) p=ls;
			else if (siz[ls]+1==k) return p;
			else k-=(siz[ls]+1),p=rs;
		}
	}
	/*void watch(int p){
		if (ls) watch(ls);
		printf("p v siz %d %d %d ls %d rs %d \n",p,v[p],siz[p],ls,rs);
		if (rs) watch(rs);
	}*/
}T;

int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d",&T.v[i]),f[i]=i;
	for (int i=1,a,b;i<=m;i++){
		scanf("%d%d",&a,&b);a=getfa(a),b=getfa(b);
		if (a!=b) T.splay(a,0),T.splay(b,0),T.merge(a,b);
	}
	scanf("%d",&Q);
	for (int i=1,a,b;i<=Q;i++){
		scanf("%s%d%d",op,&a,&b);
		if (op[0]=='B'){
			if (getfa(a)!=getfa(b)) a=getfa(a),b=getfa(b),T.splay(a,0),T.splay(b,0),T.merge(a,b);
		}
		else{
			a=getfa(a),T.splay(a,0);
			int ans=T.findrank(a,b);
			printf("%d\n",ans);
		}
	}
	return 0;
}


posted @ 2015-12-30 14:11  orzpps  阅读(143)  评论(0编辑  收藏  举报