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; }