BZOJ1455罗马游戏

左偏树裸题。

题面描述让人意识到了平面几何的重要性。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath>
const int N=1000007;
typedef long long LL;
using namespace std;
char o[5];

template<typename T> void read(T &x) {
    char ch=getchar(); x=0; T f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

int n,m,rt[N],v[N],ch[N][2],die[N],fa[N],dis[N];
#define lc ch[x][0]
#define rc ch[x][1]
int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}

int merge(int x,int y) {
    if(!(x*y)) return x^y;
    if(v[x]>v[y]) swap(x,y);
    rc=merge(rc,y);
    if(dis[lc]<dis[rc]) swap(lc,rc);
    if(!rc) dis[x]=0;
    else dis[x]=dis[rc]+1;
    return x; 
}

int main() {
#ifdef DEBUG
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
#endif
    read(n);
    for(int i=1;i<=n;i++) {rt[i]=i; fa[i]=i; read(v[i]);}
    read(m);
    while(m--) {
        int x,y;
        scanf("%s",o);
        if(o[0]=='K') {
            read(x);
            if(die[x]) {printf("0\n"); continue;}
            y=find(x);
            printf("%d\n",v[rt[y]]);
            die[rt[y]]=1;
            rt[y]=merge(ch[rt[y]][0],ch[rt[y]][1]);
        }
        else {
            read(x); read(y);
            if(die[x]||die[y]) continue;
            int u=find(x),v=find(y);
            if(u!=v) {
                fa[u]=rt[v];
                rt[v]=merge(rt[v],rt[u]);
            }
        }
    }
    return 0;
}
View Code

 

posted @ 2017-12-16 07:10  啊宸  阅读(159)  评论(0编辑  收藏  举报