平衡树+启发式合并+并查集
因为要求一坨数中第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\n",kth(f1,y)); 105 } 106 else solvemerge(); 107 } 108 return 0; 109 }
时间: 2024-12-25 09:40:01