有这么一群猴子,他们喜欢打架,要是两个猴子没打过就会开打,打完后自己的val值减半,然后他们就变成好基友,他们之前各自的好基友
也变成了好基友,当两只猴子决斗时,并不一定是他们打,而是他们各自的好基友里面val值最大的出来打,如果他们本来就是好基友
那么就不打了,output -1,否则output 打完后最大的val值:
利用左偏树求解,读入数据时为每一个猴子建立一颗左偏树,当两个猴子打架时,分别弹出root,然后打完,val减半,再将两个root和
剩下的左偏树进行合并:
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 1111111
#define typec int // type of key val
using namespace std;
const int na = -1;
int swap(int &x,int &y)
{
int t = x;
x = y;
y = t;
}
struct node
{
typec key;
int l, r, f, dist,id;
} tr[N];
int iroot(int i) // find i's root
{
if (i == na) return i;
while (tr[i].f != na) i = tr[i].f;
return i;
}
int merge(int rx, int ry)
{
// two root: rx, ry
if (rx == na) return ry;
if (ry == na) return rx;
if (tr[rx].key < tr[ry].key)
swap(rx, ry);
int r = merge(tr[rx].r, ry);
tr[rx].r = r;
tr[r].f = rx;
if (tr[r].dist > tr[tr[rx].l].dist)
swap(tr[rx].l, tr[rx].r);
if (tr[rx].r == na) tr[rx].dist = 0;
else tr[rx].dist = tr[tr[rx].r].dist + 1;
return rx; // return new root
}
int ins(int i, typec key, int root)
{
// add a new node(i, key)
tr[i].key = key;
tr[i].l = tr[i].r = tr[i].f = na;
tr[i].dist = 0;
return root = merge(root, i); // return new root
}
int del(int i)
{
// delete node i
if (i == na) return i;
int x, y, l, r;
l = tr[i].l;
r = tr[i].r;
y = tr[i].f;
tr[i].l = tr[i].r = tr[i].f = na;
tr[x = merge(l, r)].f = y;
if (y != na && tr[y].l == i)
tr[y].l = x;
if (y != na && tr[y].r == i)
tr[y].r = x;
for ( ; y != na; x = y, y = tr[y].f)
{
if (tr[tr[y].l].dist < tr[tr[y].r].dist)
swap(tr[y].l, tr[y].r);
if (tr[tr[y].r].dist + 1 == tr[y].dist) break;
tr[y].dist = tr[tr[y].r].dist + 1;
}
if (x != na)
return iroot(x); // return new root
else return iroot(y);
}
node top(int root)
{
return tr[root];
}
node pop(int &root)
{
node out = tr[root];
int l = tr[root].l, r = tr[root].r;
tr[root].l = tr[root].r = tr[root].f = na;
tr[l].f = tr[r].f = na;
root = merge(l, r);
return out;
}
int add(int i, typec val) // tr[i].key += val
{
if (i == na) return i;
if (tr[i].l == na && tr[i].r == na && tr[i].f == na)
{
tr[i].key += val;
return i;
}
typec key = tr[i].key + val;
int rt = del(i);
return ins(i, key, rt);
}
int init(int n)
{
for (int i = 1; i <= n; i++)
{
scanf("%d", &tr[i].key); //%d: type of key
tr[i].l = tr[i].r = tr[i].f = na;
tr[i].dist = 0;
tr[i].id=i;
}
}
int main()
{
int root = -1;
int a1,a2,a3,root1,root2;
int m,n,i;
while(scanf("%d",&n)==1)
{
init(n);
scanf("%d",&m);
for(i=0; i<m; i++)
{
scanf("%d%d",&a1,&a2);
root1=iroot(a1);
root2=iroot(a2);
if(root1==root2)
{
printf("-1\n");
continue;
}
else
{
node top1,top2;
top1=pop(root1);
top2=pop(root2);
tr[top1.id].key/=2;
tr[top2.id].key/=2;
top1.l = top1.r = top1.f = na;
top1.dist = 0;
top2.l = top2.r = top2.f = na;
top2.dist = 0;
root1=merge(root1,top1.id);
root1=merge(root1,top2.id);
root1=merge(root1,root2);
top1=top(root1);
printf("%d\n",top1.key);
}
}
}
}