Monkey King
忽然看到左偏树,挺简单的,抄了个模板题练练
1 //左偏树 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn = 100010; 5 struct Node{ 6 int val, dis, l, r; 7 }p[maxn]; 8 int f[maxn]; 9 int gf(int x){ 10 return x == f[x] ? f[x] : f[x] = gf(f[x]); 11 } 12 inline void maintain(int rt){ 13 f[p[rt].r] = rt; 14 } 15 int merge(int x, int y){ 16 if(!x) return y; 17 if(!y) return x; 18 if(p[x].val < p[y].val) swap(x, y); 19 p[x].r = merge(p[x].r, y); 20 maintain(x); // 维护右子树的父亲 21 int l = p[x].l, r = p[x].r; 22 if(p[l].dis < p[r].dis) swap(p[x].l, p[x].r); 23 if(p[x].r == 0) p[x].dis = 0; 24 else p[x].dis = p[p[x].r].dis + 1; 25 return x; 26 } 27 int pop(int x){ 28 int l = p[x].l, r = p[x].r; 29 p[x].dis = 0; 30 p[x].l = p[x].r = 0; 31 f[l] = l; f[r] = r; //维护父亲 32 return merge(l, r); 33 } 34 int main(){ 35 int n, m; 36 while(scanf("%d", &n) != EOF){ 37 for(int i = 1; i <= n; i++){ 38 scanf("%d", &p[i].val); 39 p[i].l = p[i].r = p[i].dis = 0; 40 f[i] = i; 41 } 42 scanf("%d", &m); 43 while(m--){ 44 int a, b; 45 scanf("%d %d", &a, &b); 46 int pa = gf(a), pb = gf(b); 47 if(pa == pb) puts("-1"); 48 else{ 49 p[pa].val /= 2; 50 p[pb].val /= 2; 51 int l = pop(pa), r = pop(pb); 52 l = merge(l, pa); 53 r = merge(r, pb); 54 l = merge(l, r); 55 printf("%d\n", p[l].val); 56 } 57 } 58 } 59 return 0; 60 }