• 【BZOJ】【2733】【HNOI2012】永无乡


    平衡树+启发式合并+并查集

      因为要求一坨数中第k大的……用平衡树会很好维护……

      但又要求连通块?所以用并查集来维护……

      大概就是让并查集的fa和Treap的根是同一个节点吧……

    TLE了N多发,可能是Treap的随机rank看脸的原因……QAQ

    唯一过了的一次是小号……

      1 /**************************************************************
      2     Problem: 2733
      3     User: ProgrammingApe
      4     Language: C++
      5     Result: Accepted
      6     Time:2356 ms
      7     Memory:3640 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 2733
     11 #include<cstdio>
     12 #include<cstdlib>
     13 #include<cstring>
     14 #include<iostream>
     15 #include<algorithm>
     16 #define rep(i,n) for(int i=0;i<n;++i)
     17 #define F(i,j,n) for(int i=j;i<=n;++i)
     18 #define D(i,j,n) for(int i=j;i>=n;--i)
     19 using namespace std;
     20  
     21 inline int getint(){
     22     int v=0,sign=1; char ch=getchar();
     23     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
     24     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
     25     return v*=sign;
     26 }
     27 /*******************tamplate********************/
     28 const int N=100010;
     29 struct node{
     30     int ch[2];
     31     int rk,v,size;
     32     node(){}
     33     #define L t[o].ch[0]
     34     #define R t[o].ch[1]
     35 }t[N];
     36 int fa[N],n;
     37 int getfa(int x){ return fa[x]==x ? x : getfa(fa[x]); }
     38 inline void push_up(int o){
     39     t[o].size=t[L].size+t[R].size+1;
     40 }
     41 inline void rotate(int &o,int d){
     42     int k=t[o].ch[!d];
     43     t[o].ch[!d]=t[k].ch[d];
     44     t[k].ch[d]=o;
     45     push_up(o);
     46     o=k;
     47 }
     48 inline void insert(int &o,int x){
     49     if (!o){
     50         o=x; t[o].size=1; L=R=0;
     51         t[o].rk=rand();
     52     }
     53     else{
     54         t[o].size++;
     55         if (t[x].v<t[o].v){
     56             insert(L,x);
     57             if (t[L].rk<t[o].rk) rotate(o,1);
     58         }
     59         else{
     60             insert(R,x);
     61             if (t[R].rk<t[o].rk) rotate(o,0);
     62         }
     63         push_up(o);
     64     }
     65 }
     66 inline void merge(int x,int y){//将x向y合并
     67     if (x==0) return;
     68     merge(t[x].ch[0],y); merge(t[x].ch[1],y);
     69     insert(y,x);
     70 }
     71 inline void solvemerge(){
     72     int x=getint(), y=getint();
     73     int f1=getfa(x),f2=getfa(y);
     74     if (f1==f2) return;
     75     if (t[f1].size>t[f2].size) swap(f1,f2);
     76     fa[f1]=f2;
     77     merge(f1,f2);
     78 }
     79 inline int kth(int o,int k){
     80     while(o){
     81         if (!o || k<=0 || k>t[o].size) return -1;
     82         int s=t[L].size;
     83         if (k==s+1) return o;
     84         else if (k<=s) o=L;
     85         else {o=R; k=k-s-1;}
     86     }
     87     return -1;
     88 }
     89 int main(){
     90     n=getint();
     91     int m=getint(),x,y;
     92     F(i,1,n){
     93         t[i].v=getint();
     94         fa[i]=i; t[i].size=1; t[i].ch[0]=t[i].ch[1]=0;
     95     }
     96     F(i,1,m) solvemerge();
     97     int q=getint();
     98     char cmd[3];
     99     F(i,1,q){
    100         scanf("%s",cmd);
    101         if (cmd[0]=='Q'){
    102             x=getint(); y=getint();
    103             int f1=getfa(x);
    104             printf("%d
    ",kth(f1,y));
    105         }
    106         else solvemerge();
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    windows10装机小记
    Linus Benedict Torvalds hate FUD
    营销文章good
    商城趣聊4
    商城趣聊3
    商城趣聊2
    商城趣聊1
    temp
    学习代码检视方法 (摘自某图片)
    xilinx sdk闪退问题
  • 原文地址:https://www.cnblogs.com/Tunix/p/4294774.html
Copyright © 2020-2023  润新知