左偏树什么的已经忘记啦,但是平板电视是忘不掉的。
我们只需要来这么一下:
#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;
}