首页 > 代码库 > BZOJ 1455: 罗马游戏

BZOJ 1455: 罗马游戏

Description

支持合并和求最小值。

Solution

可并堆-左偏树。

前几天随便看了一下...感觉也挺好写的...

Code

/**************************************************************    Problem: 1455    User: BeiYu    Language: C++    Result: Accepted    Time:1628 ms    Memory:24728 kb****************************************************************/ #include <bits/stdc++.h>using namespace std; const int N = 1000050; inline int in(int x=0,char ch=getchar()) { while(ch>‘9‘ || ch<‘0‘) ch=getchar();    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();return x; } int n,m;int A[N],D[N],L[N],R[N],f[N];int b[N]; int find(int x) { return f[x]==x?x:f[x]=find(f[x]); }int Merge(int x,int y) {    if(!x||!y) return y?y:x;    if(A[x]>A[y]) swap(x,y);    R[x]=Merge(R[x],y);    if(D[L[x]]<D[R[x]]) swap(L[x],R[x]);    D[x]=D[R[x]]+1;    return x;}void Del(int x) {    b[x]=0,f[x]=Merge(L[x],R[x]),f[f[x]]=f[x];} int main() {    n=in();    for(int i=1;i<=n;i++) A[i]=in(),f[i]=i,b[i]=1;    for(m=in();m--;) {        char opt[15];        scanf("%s",opt);        if(opt[0]==‘M‘) {            int u=in(),v=in();            if(!b[u] || !b[v]) continue;            u=find(u),v=find(v);            if(u^v) f[u]=f[v]=Merge(u,v);        } else {             int ans=0,u=in();             if(b[u]) u=find(u),ans=A[u],Del(u);             printf("%d\n",ans);        }    }    return 0;}

  

BZOJ 1455: 罗马游戏