[Luogu3377]【模板】左偏树(可并堆)

题面戳我
题目描述
如题,一开始有N个小根堆,每个堆包含且仅包含一个数。接下来需要支持两种操作:
操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删除或第x和第y个数在用一个堆内,则无视此操作)
操作2: 2 x 输出第x个数所在的堆最小数,并将其删除(若第x个数已经被删除,则输出-1并无视删除操作)
输入输出格式
输入格式:
第一行包含两个正整数N、M,分别表示一开始小根堆的个数和接下来操作的个数。
第二行包含N个正整数,其中第i个正整数表示第i个小根堆初始时包含且仅包含的数。
接下来M行每行2个或3个正整数,表示一条操作,格式如下:
操作1 : 1 x y
操作2 : 2 x
输出格式:
输出包含若干行整数,分别依次对应每一个操作2所得的结果。
输入输出样例
输入样例#1:

5 5
1 5 4 2 3
1 1 5
1 2 5
2 2
1 4 2
2 2

输出样例#1:

1
2

说明
当堆里有多个最小值时,优先删除原序列的靠前的,否则会影响后续操作1导致WA。
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,M<=10
对于70%的数据:N<=1000,M<=1000
对于100%的数据:N<=100000,M<=100000

sol

左偏树模板题,考虑到要讲所以就把陈年代码翻出来写一写题解。
我们考虑到左偏树的一个非常优秀的性质:树高的期望是\(logn\)
所以判断是否在同一个堆中,只要暴力跳堆顶即可。
(其实也是可以写个并查集的啦)
其他就好说了。

code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX=100005;
int key[MAX],ls[MAX],rs[MAX],fa[MAX],dis[MAX],del[MAX],n,m;
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=-1,ch=getchar();
    while (ch>='0'&&ch<='9')
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return x*w;
}

int Merge(int A,int B)
{
    if (!A) return B;
    if (!B) return A;
    if (key[A]>key[B]||(key[A]==key[B]&&A>B)) swap(A,B);
    rs[A]=Merge(rs[A],B);
    fa[rs[A]]=A;
    if (dis[ls[A]]<dis[rs[A]]) swap(ls[A],rs[A]);
    dis[A]=dis[rs[A]]+1;
    return A;
}
void Delete(int A)
{
    del[A]=1;
    fa[ls[A]]=fa[rs[A]]=0;
    Merge(ls[A],rs[A]);
}
int find(int x)
{
    while (fa[x]) x=fa[x];
    return x;
}
int main()
{
    n=gi();m=gi();
    for (int i=1;i<=n;i++) key[i]=gi();
    while (m--)
    {
        int opt=gi();
        if (opt==1)
        {
            int x=gi(),y=gi();
            int fx=find(x),fy=find(y);
            if (del[x]||del[y]||fx==fy) continue;
            Merge(fx,fy);
        }
        else
        {
            int x=gi();
            if (del[x]) printf("-1\n");
            else
            {
                int fx=find(x);
                printf("%d\n",key[fx]);
                Delete(fx);
            }
        }
    }
    return 0;
}

posted @ 2018-01-02 11:28  租酥雨  阅读(272)  评论(0编辑  收藏  举报