题目描述
Link
Solution
这道题比较麻烦的操作就是修改操作,我主要讲一下修改操作。
我是这么做的:
如果这个堆的大小是1,那么直接修改。
如果不是,则将最大权值的节点删除,新建一个节点,权值为被删除节点的权值的一半,再与之前的节点合并。
最后将两个堆合并就行了。
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define MAXN 2000010 struct Heap { int v, id; int s, xd; }h[MAXN]; int fa[MAXN], a[MAXN], siz[MAXN]; bool ifd[MAXN]; int merge(int a, int b) { if (h[a].v == 0) return b; if (h[b].v == 0) return a; if (h[a].v < h[b].v || (h[a].v == h[b].v && a < b)) std::swap(a, b); h[b].xd = h[a].s; h[a].s = b; return a; } int merges(int a) { if (h[a].v == 0 || h[h[a].xd].v == 0) return a; int p = h[a].xd, q = h[p].xd; h[a].xd = h[p].xd = 0; return merge(merge(a, p), merges(q)); } int del(int a) { h[a].v = -1; return merges(h[a].s); } int find(int x) { if (fa[x] == x) return x; else return fa[x] = find(fa[x]); } bool un(int x, int y) { fa[y] = x; return 1; } int head[MAXN], x, y, n, m, cnt; void push(int a, int &p) { cnt++; head[cnt] = cnt; h[cnt].v = a; h[cnt].id = cnt; h[cnt].s = h[cnt].xd = 0; fa[cnt] = cnt; siz[cnt] = 1; p = merge(cnt, p); } char op[5]; int main() { while (scanf("%d", &n) != EOF) { for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); fa[i] = i; } h[0].v = 0; cnt = 0; for (int i = 1; i <= n; i++) { head[i] = i; h[i].v = a[i]; h[i].id = i; h[i].s = h[i].xd = 0; siz[i] = 1; } cnt = n; scanf("%d", &m); while (m--) { scanf("%d%d", &x, &y); int _x = find(x), _y = find(y); if (_x == _y) { puts("-1"); continue; } bool fl1 = 0, fl2 = 0; if (siz[head[_x]] == 1) { h[head[_x]].v /= 2; fl1 = 1; } if (siz[head[_y]] == 1) { h[head[_y]].v /= 2; fl2 = 1; } if (!fl1) { int f = h[head[_x]].v; head[_x] = del(head[_x]); push(f / 2, head[_x]); } if (!fl2) { int g = h[head[_y]].v; head[_y] = del(head[_y]); push(g / 2, head[_y]); } un(_x, _y); head[_x] = merge(head[_x], head[_y]); siz[head[_x]] += siz[head[_y]]; printf("%d\n", h[head[_x]].v); } } }
|