可并堆

左偏树

每次往右边合并然后再交换一下左右子树就是对的??

merge函数

Node* merge(Node *x,Node *y)
{
    if(x==null) return y;
    if(y==null) return x;
    if(x->value > y->value) swap(x,y);
    x->right=merge(x->right,y);
    swap(x->left,x->right);
    return x;
}

罗马游戏

#include<iostream>
#include<cstdio>
#define M 1000010
using namespace std;

int n,m,k,f[M],x,y;
char c;
bool b[M];
int find(int x)
{
	if(f[x]==x) return x;
	return f[x]=find(f[x]);
}

struct Node
{
	int value,num;
	Node *left,*right;
	Node(int v,int n,Node *l,Node *r): value(v), num(n), left(l), right(r){}
	Node(){}
} *null,*a[M],*st[M];

Node* merge(Node *x,Node *y)
{
	if(x==null) return y;
	if(y==null) return x;
	if(x->value > y->value) swap(x,y);
	x->right=merge(x->right,y);
	swap(x->left,x->right);
	return x;
}

int main()
{
	scanf("%d",&n);
	null=new Node(0,0,0,0);
	for(int i=1;i<=n;i++) 
	{
		scanf("%d",&k); f[i]=i;
		a[i]=new Node(k,i,null,null);
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("
%c",&c);
		if(c=='M') 
		{
			scanf("%d%d",&x,&y);
			if(b[x] || b[y]) continue;
			if(find(x)==find(y)) continue;
			x=f[x], y=f[y]; f[x]=y;
			a[x]=a[y]=merge(a[x],a[y]);
		}
		else 
		{
			scanf("%d",&x); if(b[x] || a[find(x)]==null) {printf("0
"); continue;}
			x=f[x]; b[a[x]->num]=1;
			printf("%d
",a[x]->value);
			a[x]=merge(a[x]->left, a[x]->right);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/ZUTTER/p/10369475.html