bzoj 2733: [HNOI2012]永无乡
Posted ws_ccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2733: [HNOI2012]永无乡相关的知识,希望对你有一定的参考价值。
23333用并查集维护联通,然后网上搞splay就行啦。
%高端splay写法(2333写在struct里了,是不是叫构造函数什么的??)
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define LL long long 4 #define ls tr[x][0] 5 #define rs tr[x][1] 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 11 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 12 return x*f; 13 } 14 int f[N],n,m,Q,v[N],q[N],l,r;char op[5]; 15 int find(int x){return f[x]==x?x:f[x]=find(f[x]);} 16 struct Tsplay{ 17 int fa[N],tr[N][2],root,v[N],size[N]; 18 void update(int x) {size[x]=size[ls]+size[rs]+1;} 19 bool which (int x){return tr[fa[x]][1]==x;} 20 void rotate(int x) //(这个rotate看起来很不错233) 21 { 22 int y=fa[x],z=fa[y]; bool nx=which(x),ny=which(y); 23 tr[y][nx]=tr[x][!nx]; fa[tr[x][!nx]]=y; 24 fa[y]=x; tr[x][!nx]=y; fa[x]=z; 25 if (z) tr[z][ny]=x; update(y); update(x); 26 } 27 void splay(int x, int aim) //(翻转到以aim为父亲节点的点) 28 { 29 while (fa[x]!=aim) 30 { 31 int y=fa[x],z=fa[y]; 32 if (z==aim) rotate(x); 33 else if (which(x)==which(y)) rotate(y),rotate(x); 34 else rotate(x),rotate(x); 35 } 36 if (!aim) root=x; update(x); 37 } 38 void insert(int a) 39 { 40 int x=root; 41 for(;;) 42 { 43 if (v[a]<v[x]) 44 { 45 if (!ls) return ls=a,fa[a]=x,splay(a,0),void(); 46 else x=ls; 47 } 48 else 49 { 50 if (!rs) return rs=a,fa[a]=x,splay(a,0),void(); 51 else x=rs; 52 } 53 } 54 } 55 void merge(int a, int b) 56 { 57 if (size[a]<size[b]) swap(a,b); 58 f[b]=a,root=a; 59 l=0,r=1; q[0]=b; 60 while (l<r) 61 { 62 int x=q[l++]; 63 if (ls) q[r++]=ls; 64 if (rs) q[r++]=rs; 65 ls=rs=0; size[x]=1; insert(x); 66 } 67 splay(a,0); 68 } 69 int rank(int a, int k) 70 { 71 if (k>size[a]) return -1; 72 int x=root; 73 for(;;) 74 { 75 if (size[ls]>=k) x=ls; 76 else if (size[ls]+1==k) return x; 77 else k-=(size[ls]+1),x=rs; 78 } 79 } 80 }T; 81 int main() 82 { 83 n=ra(); m=ra(); 84 for (int i=1; i<=n; i++) T.v[i]=ra(),f[i]=i; 85 for (int i=1; i<=m; i++) 86 { 87 int p=find(ra()),q=find(ra()); 88 if (p!=q) T.splay(q,0),T.splay(p,0),T.merge(q,p); 89 } 90 int t=ra(); 91 while (t--) 92 { 93 int a,b; 94 scanf("%s%d%d",op,&a,&b); 95 if (op[0]==‘B‘) { 96 if (find(a)!=find(b)) a=find(a),b=find(b),T.splay(a,0),T.splay(b,0),T.merge(a,b); 97 } 98 else 99 { 100 a=find(a); T.splay(a,0); 101 printf("%d\n",T.rank(a,b)); 102 } 103 } 104 return 0; 105 }
以上是关于bzoj 2733: [HNOI2012]永无乡的主要内容,如果未能解决你的问题,请参考以下文章
[BZOJ] 2733: [HNOI2012]永无乡 #线段树合并+并查集