首页 > 其他 > 详细

洛谷 P3377 模板左偏树

时间:2018-08-15 23:28:29      阅读:217      评论:0      收藏:0      [点我收藏+]

题目:https://www.luogu.org/problemnew/show/P3377

左偏树的模板题;

加深了我对空 merge 的理解;

结构体的编号就是原序列的位置。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const maxn=1e5+5;
int n,m,rt[maxn],fa[maxn];
bool out[maxn];
struct N{
    int ls,rs,val,dis;
}t[maxn];
int get(int x){while(rt[x])x=rt[x]; return x;}
int merge(int x,int y)
{
    if(!x||!y)return x+y;
    if(t[x].val>t[y].val||(t[x].val==t[y].val&&x>y))swap(x,y);
    t[x].rs=merge(t[x].rs,y);
    if(t[t[x].ls].dis<t[t[x].rs].dis)swap(t[x].ls,t[x].rs);
    if(t[x].rs)t[x].dis=t[t[x].rs].dis+1;
    else t[x].dis=0;
    rt[t[x].ls]=rt[t[x].rs]=x;
    return x;
}
void del(int x)
{
    out[x]=1;
    rt[t[x].ls]=rt[t[x].rs]=0;
    merge(t[x].ls,t[x].rs);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,x;i<=n;i++){scanf("%d",&x); t[i].val=x;}
    for(int i=1,op,x,y,u,v;i<=m;i++)
    {
        scanf("%d%d",&op,&x);
        if(op==1)
        {
            scanf("%d",&y);
            if(out[x]||out[y])continue;
            u=get(x); v=get(y);
            if(u==v)continue;
            merge(u,v);
        }
        else
        {
            if(out[x]){printf("-1\n"); continue;}
            u=get(x); printf("%d\n",t[u].val);
            del(u);
        }
    }
    return 0;
}

 

洛谷 P3377 模板左偏树

原文:https://www.cnblogs.com/Zinn/p/9484279.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!