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]永无乡的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2733: [HNOI2012]永无乡 启发式合并

[BZOJ] 2733: [HNOI2012]永无乡 #线段树合并+并查集

Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并

bzoj 2733: [HNOI2012]永无乡

BZOJ2733: [HNOI2012]永无乡

[bzoj2733] [HNOI2012]永无乡