可爱的左偏树

讲解会单独写

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #define inf 2147483600
 6 #define rep(i,a,n) for(int i = a;i <= n;i++)
 7 #define per(i,n,a) for(int i = n;i >= a;i--)
 8 using namespace std;
 9 typedef long long ll;
10 int read() {
11     int as = 0,fu = 1;
12     char c = getchar();
13     while(c < '0' || c > '9') {
14         if(c == '-') fu = -1;
15         c = getchar();
16     }
17     while(c >= '0' && c <= '9') {
18         as = as * 10 + c - '0';
19         c = getchar();
20     }
21     return as * fu;
22 }
23 
24 //head===============================w=
25 
26 const int N = 100005;
27 
28 int v[N],ls[N],rs[N],pa[N],dist[N];
29 
30 int gpa(int x) {
31     while(pa[x]) x = pa[x];
32     return x;
33 }
34 
35 int Merge(int x,int y) {
36     if(!x || !y) return x | y;
37     if(v[x] > v[y] || (v[x] == v[y] && x > y)) swap(x,y);
38     rs[x] = Merge(rs[x],y);
39     pa[rs[x]] = x;
40     if(d[ls[x]] < d[rs[x]]) swap(ls[x],rs[x]);
41     dist[x] = dist[rs[x]] + 1;
42     return x;
43 }
44 
45 void Del(int x) {
46     v[x] = -1;
47     pa[ls[x]] = pa[rs[x]] = 0;
48     Merge(ls[x],rs[x]);
49     return;
50 }
51 
52 int main() {
53     int n = read();
54     int m = read();
55     rep(i,1,n) v[i] = read();
56     while(m--) {
57         int op = read();
58         if(op == 1) {
59             int x = read();
60             int y = read();
61             if(v[x] == -1 || v[y] == -1 || x == y) continue;
62             Merge(gpa(x),gpa(y));
63         } else {
64             int x = read();
65             if(v[x] == -1) {
66                 printf("-1\n");
67                 continue;
68             }
69             int y = gpa(x);
70             printf("%d\n",v[y]);
71             Del(y);
72         }
73     }
74     
75     return 0;
76 }

通过左偏来支持合并

猜你喜欢

转载自www.cnblogs.com/yuyanjiaB/p/9327884.html