【bzoj1455】罗马游戏
罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。
皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。他决定玩这样一个游戏。 它可以发两种命令:
1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。
2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。
皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)
左偏树(堆)裸题;
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<set> #include<map> #include<queue> #include<algorithm> #include<iomanip> #include<stack> using namespace std; #define FILE "dealing" #define up(i,j,n) for(int i=(j);i<=(n);i++) #define pii pair<int,int> #define LL int #define mem(f,g) memset(f,g,sizeof(f)) namespace IO{ char buf[1<<15],*fs,*ft; int gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;} int read(){ int ch=gc(),f=0,x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} return f?-x:x; } int readint(){ int ch=getchar(),f=0,x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f?-x:x; } }using namespace IO; const int maxn=1001000,inf=100000000; int n,m,x,y; int fa[maxn],d[maxn],die[maxn],l[maxn],r[maxn],v[maxn]; char ch; inline void swap(int &a,int &b){a=a^b,b=b^a,a=a^b;} int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} int Union(int x,int y){ if(!x)return y; if(!y)return x; if(v[x]>v[y])swap(x,y); r[x]=Union(r[x],y); if(d[r[x]]>d[l[x]])swap(r[x],l[x]); d[x]=d[r[x]]+1; return x; } int main(){ n=read(); up(i,1,n)v[i]=read(),fa[i]=i; m=read(); while(m--){ ch=gc(); if(ch=='M'){ x=read(),y=read(); if(die[x]||die[y])continue; x=find(x),y=find(y); if(x!=y){ int t=Union(x,y); fa[x]=fa[y]=t; } } else { x=read(); if(die[x])printf("0\n"); else { x=find(x);die[x]=1; fa[x]=Union(l[x],r[x]); fa[fa[x]]=fa[x]; printf("%d\n",v[x]); } } } return 0; }