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;
}

  

posted @ 2017-03-14 16:26  北北北北屿  阅读(119)  评论(0编辑  收藏  举报