可并堆
左偏树
每次往右边合并然后再交换一下左右子树就是对的??
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("\n%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\n"); continue;}
x=f[x]; b[a[x]->num]=1;
printf("%d\n",a[x]->value);
a[x]=merge(a[x]->left, a[x]->right);
}
}
return 0;
}