…左偏树模板.
然后我MLE爆了…
原因是修改堆顶元素是先取出来后合并进去,然后取出来的时候没有把儿子清空,然后merge内就栈溢出了…
开始我写的指针,sb地以为是多组数据指针内存爆了,然后写回收内存…还是MLE,搞得我有指针恐惧症了…
CODE
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100005;
struct lt {
int ls, rs, fa, v, d;
}t[MAXN];
int merge(int x, int y) {
if(!x || !y) return x + y;
if(t[y].v > t[x].v) swap(x, y);
t[x].rs = merge(t[x].rs, y);
t[t[x].rs].fa = x;
if(t[t[x].ls].d < t[t[x].rs].d)
swap(t[x].ls, t[x].rs);
t[x].d = t[t[x].rs].d + 1;
return x;
}
inline int pop(int x) {
int l = t[x].ls, r = t[x].rs;
t[x].ls = t[x].rs = t[x].d = 0; //就是这里!!
t[x].fa = t[l].fa = t[r].fa = -1;
return merge(l, r);
}
int n, m;
int find(int x) { return t[x].fa == -1 ? x : t[x].fa = find(t[x].fa); }
int main () {
t[0].d = -1;
while(~scanf("%d", &n)) {
for(int i = 1; i <= n; ++i) {
scanf("%d", &t[i].v); t[i].fa = -1;
t[i].ls = t[i].rs = t[i].d = 0;
}
scanf("%d", &m);
for(int i = 1, x, y; i <= m; ++i) {
scanf("%d%d", &x, &y);
x = find(x), y = find(y);
if(x == y) puts("-1");
else {
t[x].v >>= 1; x = merge(pop(x), x);
t[y].v >>= 1; y = merge(pop(y), y);
printf("%d
", t[merge(x, y)].v);
}
}
}
}