1455: 罗马游戏|左偏树

写个stl被卡内存..woc..smg非得逼我学左偏树..
似乎比堆更好写的样子。
有一个值得注意的细节,删除节点的时候别忘了 fa[fa[fx]]=fa[fx]; 要不然容易把并查集搞乱了,然后找不到fa了..

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define pa pair<int,int>
#define ll long long
#define N 1000005
#define mx 1e9
using namespace std;
int sc()
{
    int i=0,f=1; char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i*f;
}
int n,m,fa[N],l[N],r[N],d[N],v[N];
bool die[N];
int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
int merge(int x,int y)
{
    if(x*y==0)return x+y;
    if(v[x]>v[y])swap(x,y);
    r[x]=merge(r[x],y);
    if(d[r[x]]>d[l[x]])swap(l[x],r[x]);
    d[x]=d[r[x]]+1;
    return x;
}
int main()
{
    n=sc();
    for(int i=1;i<=n;i++)
        v[fa[i]=i]=sc();
    d[0]=-1;
    m=sc();
    while(m--)
    {
        char s[5]; scanf("%s",s);
        if(s[0]=='K')
        {
            int x=sc(),fx=find(x);
            if(die[x]){puts("0");continue;}
            printf("%d\n",v[fx]);
            die[fx]=1;
            fa[fx]=merge(l[fx],r[fx]);
            fa[fa[fx]]=fa[fx];

        }
        else
        {
            int x=sc(),y=sc();
            if(die[x]||die[y])continue;
            int fx=find(x),fy=find(y);
            if(fx!=fy)
                fa[fx]=fa[fy]=merge(fx,fy);
        }
    }
    return 0;
}

你可能感兴趣的:(左偏树)