• bzoj2733


    并查集+treap+启发式合并

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<ctime>
      6 #include<iostream>
      7 #include<algorithm>
      8 #include<queue>
      9 #include<stack>
     10 #include<set>
     11 #define rep(i,l,r) for(int i=(l);i<(r);i++)
     12 #define clr(a,x) memset(a,x,sizeof(a))
     13 using namespace std;
     14 typedef long long ll;
     15 typedef pair<int,int> pii;
     16 #define mkp(a,b) make_pair((a),(b))
     17 int read(){
     18     int ans=0,f=1;
     19     char c=getchar();
     20     while(!isdigit(c)){
     21         if(c=='-') f=-1;
     22         c=getchar();
     23     }
     24     while(isdigit(c)){
     25         ans=ans*10+c-'0';
     26         c=getchar();
     27     }
     28     return ans*f;
     29 }
     30 const int maxn=500009;
     31 struct node{
     32     int s,v,p,r;
     33     node*ch[2];
     34     void maintain(){
     35         s=ch[0]->s+ch[1]->s+1;
     36     }
     37 };
     38 node pool[maxn<<2],*root[maxn],*pt=pool,*null;
     39 int n,m,q,p[maxn],f[maxn];
     40 node*newnode(int x,int cnt){
     41     pt->s=1;pt->v=x;pt->p=cnt;pt->r=rand();
     42     pt->ch[0]=pt->ch[1]=null;
     43     return pt++;
     44 }
     45 int find(int x){
     46     return f[x]==x?f[x]:f[x]=find(f[x]);
     47 }
     48 void rot(node*&o,int d){
     49     node*t=o->ch[d^1];
     50     o->ch[d^1]=t->ch[d];t->ch[d]=o;
     51     o->maintain();t->maintain();
     52     o=t;
     53 }
     54 void insert(node*&o,node*x){
     55     if(o==null){
     56         o=newnode(x->v,x->p);
     57     }else if(x->v<o->v){
     58         insert(o->ch[0],x);
     59         if(o->ch[0]->r>o->r) rot(o,1);
     60     }else{
     61         insert(o->ch[1],x);
     62         if(o->ch[1]->r>o->r) rot(o,0);
     63     }
     64     o->maintain();
     65 }
     66 int query(node*o,int x){
     67     int t=o->ch[0]->s;
     68     if(x==t+1) return o->p;
     69     if(x<t+1) return query(o->ch[0],x);
     70     return query(o->ch[1],x-t-1);
     71 }
     72 int X;
     73 void join(node*o){
     74     if(o==null) return;
     75     join(o->ch[0]);
     76     insert(root[X],o);
     77     join(o->ch[1]);
     78 }
     79 void merge(int x,int y){
     80     int u=find(x),v=find(y);
     81     if(u==v) return;
     82     if(root[u]->s<root[v]->s) swap(u,v);
     83     f[v]=u;
     84     X=u;join(root[v]);
     85 }
     86 void init(){
     87     null=newnode(0,0);
     88     null->s=0;null->r=0;
     89     rep(i,1,n+1) f[i]=i;
     90     rep(i,1,n+1) root[i]=null;
     91 }
     92 int main(){
     93     n=read();m=read();
     94     init();
     95     rep(i,1,n+1){
     96         p[i]=read();p[i]=n-p[i]+1;
     97         insert(root[i],newnode(p[i],i));
     98     }
     99     rep(i,1,m+1){
    100         int from=read(),to=read();
    101         merge(from,to);
    102     }
    103     q=read();
    104     while(q--){
    105         char opt=getchar();
    106         while(opt!='Q'&&opt!='B') opt=getchar();
    107         int x=read(),y=read();
    108         if(opt=='Q') printf("%d
    ",y>root[find(x)]->s?-1:query(root[find(x)],root[find(x)]->s-y+1));
    109         else merge(x,y);
    110     }
    111     return 0;
    112 }
    View Code

    2733: [HNOI2012]永无乡

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1690  Solved: 891
    [Submit][Status][Discuss]

    Description

    永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。 
     

    Input

    输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 1 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。 对于 20%的数据 n≤1000,q≤1000 
     
    对于 100%的数据 n≤100000,m≤n,q≤300000 
     

    Output

    对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表 示所询问岛屿的编号。如果该岛屿不存在,则输出-1。 
     

    Sample Input

    5 1
    4 3 2 5 1
    1 2
    7
    Q 3 2
    Q 2 1
    B 2 3
    B 1 5
    Q 2 1
    Q 2 4
    Q 2 3

    Sample Output

    -1
    2
    5
    1
    2

    HINT

     

    Source

     
    [Submit][Status][Discuss]
  • 相关阅读:
    IDEA-各模块间引用出现问题的解决方法
    【MyBatis学习06】_parameter:解决There is no getter for property named in class java.lang.String
    《转载》JVM垃圾回收机制
    java面试复习题四
    Java中excel转换为jpg/png图片 采用aspose-cells-18.6.jar
    POI导出复杂的excel;excel公共样式类;excel拼接定制类;数据科学计数法转为普通值
    java发送邮件无法显示图片 图裂 的解决办法
    pom.xml文件最详细的讲解
    Tomcat启动报Error listenerStart错误 Context [] startup failed due to previous errors
    ora-01031:insufficient privileges解决方法
  • 原文地址:https://www.cnblogs.com/chensiang/p/4975295.html
Copyright © 2020-2023  润新知