BZOJ-1455 罗马游戏

同样是道可并堆题。配对堆模版题。

#include <cctype>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define ll long long 
#define maxn 1000009
using namespace std;
inline int read()
{
	int x=0; char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x;
}
struct node{int l, r, ch; node(){l=r=ch;}} h[maxn];


int n, m, k[maxn], roof[maxn]; bool die[maxn];
inline int Join(int v, int u)
{
	if (v==u) return v;
	if (k[v]<k[u]) swap(v, u);
	h[v].l=u, h[v].r=h[u].ch, h[h[u].ch].l=v, h[u].ch=v;
	roof[v]=u;
	return u;
}
int Top(int v){return roof[v]==v ? v : Top(roof[v]);}
int st[maxn], top;
inline int Kill(int v)
{
	die[v]=true; int ans=k[v];
	if (h[v].ch) 
	{
		top=0; int t=h[v].ch; 
		while (t) if (h[t].r)
		{
			int k=h[h[t].r].r;
			int v=h[t].r; 
			h[v].l=h[v].r=h[t].l=h[t].r=0; roof[t]=t, roof[v]=v;
			st[++top]=Join(t, v); t=k;
		}
		else
		{
			st[++top]=t; h[t].l=h[t].r=0; roof[t]=t; break;
		}
		t=st[top];
		rep(i, 1, top-1) t=Join(t, st[i]);
	}
	return ans;
}


char s[5];
int main()
{
	n=read(); rep(i, 1, n) k[i]=read(), roof[i]=i;
	m=read(); rep(i, 1, m)
	{
		scanf("%s", s);
		if (s[0]=='M') {int v=read(), u=read(); if (!die[v] && !die[u]) Join(Top(v), Top(u));}
		else {int v=read(); if (!die[v]) printf("%d\n", Kill(Top(v))); else printf("0\n");}
	}
	return 0;
}
posted @ 2015-05-05 15:32  NanoApe  阅读(99)  评论(0编辑  收藏  举报
AmazingCounters.com