P1456 Monkey King

左偏树什么的已经忘记啦,但是平板电视是忘不掉的。

我们只需要来这么一下:

#include<exts/pb_ds/priority_queue.hpp>
__gnu_pbds::priority<int> heap[maxn];
// 如果要小根堆就在int后面来个std::greater<int>

用一个冰茶姬维护集合,每次从所在集合拿出最大元素。然后启发式合并,新数添加回去,冰茶姬维护一下即可。

就这么简单。。。

同时注意一下:平板电视里面堆的join操作是把别人的join到我这里来!

代码:

#include<bits/stdc++.h>
#include<ext/pb_ds/priority_queue.hpp>
using std::cin;
using std::cout;
using std::endl;
const int maxn = 100005;
int n, m;
int val[maxn];
int fa[maxn];
__gnu_pbds::priority_queue<int> heap[maxn];
int find(int x) {
    if(fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}
int main() {
    while(cin >> n) {
        for(int i = 1; i <= n; i++) cin >> val[i];
        for(int i = 1; i <= n; i++) {
            fa[i] = i; heap[i].clear(); heap[i].push(val[i]);
        }
        cin >> m;
        while(m--) {
            int x, y; cin >> x >> y;
            if(find(x) == find(y)) cout << -1 << endl;
            else {
                x = find(x), y = find(y);
                if(heap[x].size() < heap[y].size()) std::swap(x, y);
                int temp1 = heap[x].top(); heap[x].pop();
                int temp2 = heap[y].top(); heap[y].pop();
                fa[y] = x; heap[x].join(heap[y]);
                heap[x].push(temp1 / 2);
                heap[x].push(temp2 / 2);
                cout << heap[x].top() << endl;
            }
        }
    }
    return 0;
}
posted @ 2019-06-01 14:40  Garen-Wang  阅读(150)  评论(0编辑  收藏  举报