bzoj2733: [HNOI2012]永无乡
这题是真的智障,个个都说什么启发式合并,其实就是暴力把小的那棵splay拆掉重新插入,不过就是每次判断一下那棵树的节点数少拆那棵,这样就O(nlogn^2).....
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int fa[110000]; int findfa(int x) { if(fa[x]==x)return x; fa[x]=findfa(fa[x]);return fa[x]; } //------f f-------- struct node { int x,f,c,son[2]; }tr[110000]; void update(int x) { int lc=tr[x].son[0],rc=tr[x].son[1]; tr[x].c=tr[lc].c+tr[rc].c+1; } void rotate(int x,int w) { int f=tr[x].f,ff=tr[f].f; int R,r; R=f,r=tr[x].son[w]; tr[R].son[1-w]=r; if(r!=0)tr[r].f=R; R=ff,r=x; if(tr[R].son[0]==f)tr[R].son[0]=r; else if(tr[R].son[1]==f)tr[R].son[1]=r; tr[r].f=R; R=x;r=f; tr[R].son[w]=r; tr[r].f=R; update(f); update(x); } void splay(int x,int rt) { while(tr[x].f!=rt) { int f=tr[x].f,ff=tr[f].f; if(ff==rt) { if(tr[f].son[0]==x)rotate(x,1); else rotate(x,0); } else { if(tr[ff].son[0]==f&&tr[f].son[0]==x){rotate(f,1);rotate(x,1);} else if(tr[ff].son[1]==f&&tr[f].son[1]==x){rotate(f,0);rotate(x,0);} else if(tr[ff].son[0]==f&&tr[f].son[1]==x){rotate(x,0);rotate(x,1);} else if(tr[ff].son[1]==f&&tr[f].son[0]==x){rotate(x,1);rotate(x,0);} } } } //-------splay i-------------- int findip(int x,int y) { while(1) { if(tr[x].x<tr[y].x) { if(tr[y].son[0]==0)return y; y=tr[y].son[0]; } else { if(tr[y].son[1]==0)return y; y=tr[y].son[1]; } } } void ins(int x,int y) { int f=findip(x,y); tr[x].f=f; if(tr[x].x<tr[f].x)tr[f].son[0]=x; else tr[f].son[1]=x; update(f);splay(f,0); } void dfs(int x,int y) { ins(x,y); if(tr[x].son[0]!=0)dfs(tr[x].son[0],y); if(tr[x].son[1]!=0)dfs(tr[x].son[1],y); } int findshuzi(int x,int k) { while(x!=0) { int lc=tr[x].son[0],rc=tr[x].son[1]; if(tr[lc].c>=k)x=lc; else if(tr[lc].c+1<k)k-=tr[lc].c+1, x=rc; else return x; } return -1; } //--------splay o----------- int a[110000]; char ss[10]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]);fa[i]=i; tr[i].x=a[i];tr[i].f=0;tr[i].c=1; tr[i].son[0]=tr[i].son[1]=0; } int x,y; for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); if(x==0||y==0)continue; int fx=findfa(x),fy=findfa(y); if(tr[fx].c>tr[fy].c)swap(fx,fy); if(fx!=fy)fa[fx]=fy, dfs(fx,fy), splay(fy,0); } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%s%d%d",ss+1,&x,&y); if(x==0||y==0)continue; if(ss[1]=='B') { int fx=findfa(x),fy=findfa(y); if(tr[fx].c>tr[fy].c)swap(fx,fy); if(fx!=fy)fa[fx]=fy, dfs(fx,fy), splay(fy,0); } else printf("%d\n",findshuzi(fa[x],y)); } return 0; }
pain and happy in the cruel world.