题目描述

如题,一开始有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.getf 即寻找祖先;

2.Merge 合并操作,如果是最小堆,则要满足x<y,最大堆反过来(这是我刚做这些题的时候的见解,目前认为就是这样)

然后进行合并的递归操作,最后则要满足左偏,即dis【x】>dis【y】;

         为什么要左偏?????   这可能是左偏树最重要的思想了;

        左偏之后,能保证右边的深度较小,别人创造的这一算法里,是往右子树进行合并操作,操作的时间复杂度自然是按右子树的深度来算;

        所以为了保证时间复杂度较小(logn)便要在右子树深度大于左子树时,交换两者的值;

3.pop操作,这个操作,是剔除堆中的最大值或者最小值,然后再将他的左右子树合并,其中一个成为新的根。然后再将被剔除点的父亲定为新根

为什么要定为新根呢,因为可能在下面的点中有直接指向这个点的节点。所以要将这些点指向新的。

 #include<cstdio>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
const int maxn=1e5+;
int val[maxn];
int f[maxn];
int ch[maxn][];
int dis[maxn];
int getf(int x) //标准并查集
{
if(f[x]==x) return x;
else{
f[x]=getf(f[x]);
return f[x];
}
}
int Merge(int x,int y)
{
if(!x||!y) return x+y; //到底了;
//保证最小堆性质 后面这个不懂
if(val[x]>val[y]||(val[x]==val[y]&&x>y)) swap(x,y);
//这个大概就是创这个算法的人的习惯了,将其定在右子树。
//然后再在下面进行操作来满足偏左树的性质;
ch[x][]=Merge(ch[x][],y);
f[ch[x][]]=x; //并查集操作;
//满足偏左;
if(dis[ch[x][]]<dis[ch[x][]]) swap(ch[x][],ch[x][]);
//这个是偏左树的性质,想想就知道是对的。
dis[x]=dis[ch[x][]]+;
return x;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&val[i]);
f[i]=i;
}
while(m--){
int ope;
scanf("%d",&ope);
if(ope==){
int t1,t2;
scanf("%d%d",&t1,&t2);
if(val[t1]==-||val[t2]==-) continue;
t1=getf(t1);
t2=getf(t2);
if(t1==t2) continue;
Merge(t1,t2);
}
else{
int t;
scanf("%d",&t);
if(val[t]==-){
printf("-1\n");
continue;
}
t=getf(t);
printf("%d\n",val[t]);
//这里是pop的操作,将被T出的点定为-1;
val[t]=-;
//再将原本的根指向新根,让其他原本指向旧根的点能继续指向新根
f[ch[t][]]=f[ch[t][]]=f[t]=Merge(ch[t][],ch[t][]);
//将旧根的左右儿子以及dis清零
ch[t][]=ch[t][]=dis[t]=;
}
}
return ;
}

左偏树(p3377)的更多相关文章

  1. 左偏树 P3377【模板】左偏树(可并堆)

    题目传送门 代码: /* code by: zstu wxk time: 2019/03/01 */ #include<bits/stdc++.h> using namespace std ...

  2. 洛谷 P3377 【模板】左偏树(可并堆)

    洛谷 P3377 [模板]左偏树(可并堆) 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或 ...

  3. luogu【P3377】 【模板】左偏树

    左偏树 顾名思义 向左偏的树 (原题入口) 它有啥子用呢??? 当然是进行堆的合并啦2333普通堆的合并其实是有点慢的(用优先队列的话 只能 一个pop 一个push 来操作 复杂度就是O(n log ...

  4. 模板 可并堆【洛谷P3377】 【模板】左偏树(可并堆)

    P3377 [模板]左偏树(可并堆) 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删 ...

  5. 洛谷 - P3377 - 【模板】左偏树(可并堆) - 左偏树 - 并查集

    https://www.luogu.org/problemnew/show/P3377 左偏树+并查集 左偏树维护两个可合并的堆,并查集维护两个堆元素合并后可以找到正确的树根. 关键点在于删除一个堆的 ...

  6. 洛谷 P3377 模板左偏树

    题目:https://www.luogu.org/problemnew/show/P3377 左偏树的模板题: 加深了我对空 merge 的理解: 结构体的编号就是原序列的位置. 代码如下: #inc ...

  7. 洛谷P3377 【模板】左偏树(可并堆) 题解

    作者:zifeiy 标签:左偏树 这篇随笔需要你在之前掌握 堆 和 二叉树 的相关知识点. 堆支持在 \(O(\log n)\) 的时间内进行插入元素.查询最值和删除最值的操作.在这里,如果最值是最小 ...

  8. 2021.08.01 P3377 左偏树模板

    2021.08.01 P3377 左偏树模板 P3377 [模板]左偏树(可并堆) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<iostream> ...

  9. [洛谷P3377]【模板】左偏树(可并堆)

    题目大意:有$n$个数,$m$个操作: $1\;x\;y:$把第$x$个数和第$y$个数所在的小根堆合并 $2\;x:$输出第$x$个数所在的堆的最小值 题解:左偏树,保证每个的左儿子的距离大于右儿子 ...

  10. 题解 P3377 【【模板】左偏树(可并堆)】

    所谓的左偏树,是一种可并堆的实现. 这种数据结构能够支持高效的堆合并,但是不支持查询节点等操作,因此不同于平衡树,它的结构是不平衡的. 左偏树满足如下两条基本性质: 1. 堆的性质 这也就是说左偏树每 ...

随机推荐

  1. Codeforce 588A - Duff and Meat (贪心)

    Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day ...

  2. windows-problem :电脑上网的无线图标带有黄色星号,但不影响正常上网!

    电脑可以上网,但是无线图标带有黄色星号如何解决? 进入“网络和共享中心”,点击“更改适配器设置”,看看是不是有两个以上的“本地连接”,只有一个有用,其他的删除即可.

  3. win10子系统ubuntu内的nginx启动问题

    需用sudo启动,密码是windows密码.

  4. C++——标准模板库

    1.泛型程序设计:将程序尽可能写的通用,将算法从特定的数据结构中抽象出来,成为通用的:C++模板为泛型程序设计奠定了关键的基础:STL是泛型程序设计的一个范例:容器container.迭代器itera ...

  5. opencv3.2.0+opencv_contrib-3.2.0+vs2015开发配置

    在sift算法实现中,出现了这个问题 出现问题:\vs2015opencv\vs2015\project\mode\mode\sift算法1.cpp(3): fatal error C1083: 无法 ...

  6. Allegro---层叠结构设置

     PCB层叠结构 层叠结构是一个非常重要的问题,不可忽视,一般选择层叠结构考虑以下原则: ·元件面下面(第二层)为地平面,提供器件屏蔽层以及为顶层布线提供参考平面: ·所有信号层尽可能与地平面相邻: ...

  7. Windows10 远程桌面连接失败,报CredSSP加密oracle修正错误解决办法

    最近Windows10 升级后,发现不能远程连接. 不能访问的都报下面这个错了: 原因:按照提示的微软地址,看了下大致就是服务器端没有更新,而我的win10已经更新了一个安全补丁,如果双方都没有打补丁 ...

  8. windows10 +ubuntu双系统

    1,安装之前的准备: 制作启动盘 确定给ubuntu多少分区并且清理为free状态 确定电脑的开机引导方式,传统方式引号和uefi引导并不一样,因此我们需要根据引导方式选择新系统制作什么样的启动盘 在 ...

  9. JS高级---闭包小案例

    闭包小案例 普通的函数 //普通的函数 function f1() { var num = 10; num++; return num; } console.log(f1()); //11 conso ...

  10. C#常见几种集合比较

    1. ArrayList 1.1 ArrayList是一个特殊数组,通过添加和删除元素就可以动态改变数组的长度. ArrayList集合相对于数组的优点:支持自动改变大小,可以灵活的插入元素,可以灵活 ...