bzoj 2733 永无岛
裸的splay启发式合并,其实就是用队列实现的暴力合并,轻松写过~
Neverland
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #define maxn 200000 7 using namespace std; 8 9 int c[maxn][2]; 10 int fa[maxn],f[maxn],rank[maxn],size[maxn],q[maxn]; 11 int n,m,num,p; 12 13 inline int find(int i) 14 { 15 return (!f[i])?i:f[i]=find(f[i]); 16 } 17 18 inline void update(int x) 19 { 20 if (!x) return ; 21 size[x]=size[c[x][0]]+size[c[x][1]]+1; 22 } 23 24 inline void rotate(int x) 25 { 26 int y=fa[x],z=fa[y]; 27 int p=(c[y][1]==x),q=p^1; 28 if (fa[y]) 29 if (c[z][0]==y) c[z][0]=x; else c[z][1]=x; 30 fa[x]=z; fa[y]=x; fa[c[x][q]]=y; 31 c[y][p]=c[x][q]; c[x][q]=y; 32 update(y); 33 } 34 35 inline void splay(int x) 36 { 37 while (fa[x]) 38 { 39 int y=fa[x],z=fa[y]; 40 if (fa[y]) 41 if ((c[y][0]==x)xor(c[z][0]==y)) rotate(x); else rotate(y); 42 rotate(x); 43 } 44 update(x); 45 } 46 47 inline void insert(int &t,int anc,int x) 48 { 49 if (t==0) 50 { 51 t=x; 52 fa[x]=anc; 53 size[x]=1; 54 splay(x); 55 return; 56 } 57 if (rank[x]<=rank[t]) insert(c[t][0],t,x); 58 else insert(c[t][1],t,x); 59 update(t); 60 } 61 62 inline void merge(int x,int y) 63 { 64 if (size[x]>size[y]) swap(x,y); 65 splay(x); splay(y); 66 int head=0,tail=1; 67 q[0]=y; q[1]=x; 68 while (head<tail) 69 { 70 int now=q[++head]; 71 if (c[now][0]) q[++tail]=c[now][0]; 72 if (c[now][1]) q[++tail]=c[now][1]; 73 c[now][0]=c[now][1]=0; 74 insert(q[head-1],0,now); 75 } 76 //splay(x); 77 } 78 79 inline int search(int t,int k) 80 { 81 if (k>size[t]) return -1; 82 if (k==size[c[t][0]]+1) return t; 83 if (k<size[c[t][0]]+1) return search(c[t][0],k); 84 if (k>size[c[t][0]]+1) return search(c[t][1],k-size[c[t][0]]-1); 85 } 86 87 int main() 88 { 89 //freopen("never.in","r",stdin); 90 scanf("%d %d",&n,&m); 91 for (int i=1;i<=n;i++) scanf("%d",&rank[i]),size[i]=1; 92 int x,y; 93 for (int i=1;i<=m;i++) 94 { 95 scanf("%d %d",&x,&y); 96 if (find(x)!=find(y)) 97 { 98 merge(x,y); 99 f[find(x)]=find(y); 100 } 101 } 102 //for (int i=0;i<=n;i++) cout<<i<<' '<<fa[i]<<' '<<c[i][0]<<' '<<c[i][1]<<' '<<size[i]<<endl; 103 scanf("%d\n",&p); 104 char sign; 105 for (int i=1;i<=p;i++) 106 { 107 scanf("%c %d %d\n",&sign,&x,&y); 108 //cout<<sign<<endl; 109 if (sign=='B') 110 { 111 if (find(x)!=find(y)) 112 { 113 merge(x,y); 114 f[find(x)]=find(y); 115 } 116 } 117 else 118 { 119 splay(x); 120 int ans=search(x,y); 121 printf("%d\n",ans); 122 } 123 } 124 return 0; 125 }
AC without art, no better than WA !