zoukankan      html  css  js  c++  java
  • 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
    ",T.rank(a,b));
    102         }
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    如何使用android模拟器截图
    android SD卡文件的读写
    res/raw下的资源文件读写
    window 运行指令(1)
    javax.swing.JOptionPane.showMessageDialog() 方法
    Eclipse快捷键
    EditPlus怎样自动换行
    java的HashCode方法
    eclipse汉化全程
    (转载)jdbc事务处理
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6392031.html
Copyright © 2011-2022 走看看