您的位置:首页 > 其它

[bzoj1455]罗马游戏

2016-06-01 20:24 411 查看

题目大意

需要兹瓷集合合并与删去集合内最小值。

可并堆

还能说什么呢,裸的……

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=1000000+10;
int fa[maxn],dis[maxn],left[maxn],right[maxn],a[maxn],root[maxn];
bool bz[maxn];
int i,j,k,l,t,n,m;
char ch;
char get(){
char ch=getchar();
while (ch!='M'&&ch!='K') ch=getchar();
return ch;
}
int read(){
int x=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
int getfa(int x){
return fa[x]?fa[x]=getfa(fa[x]):x;
}
int merge(int x,int y){
if (!x||!y) return x+y;
if (a[x]>a[y]) swap(x,y);
right[x]=merge(right[x],y);
if (dis[left[x]]<dis[right[x]]) swap(left[x],right[x]);
dis[x]=dis[right[x]]+1;
return x;
}
int deletemin(int x){
return merge(left[x],right[x]);
}
int main(){
n=read();
fo(i,1,n) a[i]=read(),root[i]=i;
m=read();
fo(i,1,m){
ch=get();
if (ch=='M'){
j=read();k=read();
if (bz[j]||bz[k]) continue;
j=getfa(j);
k=getfa(k);
if (j==k) continue;
fa[j]=k;
root[k]=merge(root[j],root[k]);
}
else{
j=read();
if (bz[j]) printf("0\n");
else{
j=getfa(j);
printf("%d\n",a[root[j]]);
bz[root[j]]=1;
root[j]=deletemin(root[j]);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: