hdu 1512 Monkey King (左偏树 实现 可并堆)
模板:http://hi.baidu.com/cjn1466572108/item/c2b7c13e58f7aba1b711dba6
待验证
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i >= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(a, v) memset(a, v, sizeof(a))
#define PB push_back
#define MP make_pair
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 310000;
struct Node{
int l, r;
int fa;
int v, dis;
bool operator<(const Node &rhs) const
{
return v < rhs.v;///大顶堆
}
}N[maxn];
int root[maxn];
int findset(int x)
{
return x == N[x].fa ? x : N[x].fa = findset(N[x].fa);
}
void Newnode(int i, int val)
{
N[i].l = N[i].r = 0;
N[i].fa = i;
N[i].dis = 0;
N[i].v = val;
}
void Init(int n)
{
N[0].l = N[0].r = 0;
N[0].v = 0; N[0].dis = -1;
N[0].fa = 0;
int val;
for (int i = 1; i <= n; i++)
{
scanf("%d", &val);
Newnode(i, val);
}
}
int Merge(int A, int B)
{
if (A == 0) return B;
if (B == 0) return A;
if (N[A] < N[B]) swap(A, B);
N[A].r = Merge(N[A].r, B);
N[N[A].r].fa = A;///
if (N[N[A].l].dis < N[N[A].r].dis) swap(N[A].l, N[A].r);
N[A].dis = N[N[A].r].dis + 1;
return A;
}
int pop(int x)
{
int l = N[x].l;
int r = N[x].r;
N[l].fa = l;///
N[r].fa = r;///
return Merge(l, r);
}
int main ()
{
int n, m;
int x, y, fax, fay;
while (scanf("%d", &n) != EOF)
{
Init(n);
scanf("%d", &m);
while (m--)
{
scanf("%d%d",&x, &y);
fax = findset(x); fay = findset(y);
if (fax == fay) printf("-1\n");
else
{
int A = pop(fax);
Newnode(fax, N[fax].v / 2);
A = Merge(A, fax);
int B = pop(fay);
Newnode(fay, N[fay].v / 2);
B = Merge(B, fay);
printf("%d\n", N[Merge(A, B)].v);
}
}
}
return 0;
}