模板 可并堆【洛谷P3377】 【模板】左偏树(可并堆)
P3377 【模板】左偏树(可并堆)
如题,一开始有N个小根堆,每个堆包含且仅包含一个数。接下来需要支持两种操作:
操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删除或第x和第y个数在用一个堆内,则无视此操作)
操作2: 2 x 输出第x个数所在的堆最小数,并将其删除(若第x个数已经被删除,则输出-1并无视删除操作)
code:
// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
using namespace std;
const int wx=200017;
inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
}
int n,m;
int val[wx],f[wx],dis[wx];
int ch[wx][3];
int merge(int x,int y){
if(x==0||y==0) return x+y;
if((val[x]>val[y])||(val[x]==val[y]&&x>y))swap(x,y);
ch[x][1]=merge(ch[x][1],y); f[ch[x][1]]=x;
if(dis[ch[x][1]]>dis[ch[x][0]])swap(ch[x][1],ch[x][0]);
dis[x]=dis[ch[x][1]]+1; return x;
}
int getf(int x){
while(f[x])x=f[x];
return x;
}
void pop(int x){
val[x]=-1;
f[ch[x][1]]=f[ch[x][0]]=0;
merge(ch[x][0],ch[x][1]);
}
int main(){
n=read(); m=read();
for(int i=1;i<=n;i++) val[i]=read();
for(int i=1;i<=m;i++){
int opt; opt=read();
if(opt==1){
int x,y; x=read(); y=read();
if(x==y||val[x]==-1||val[y]==-1)continue;
int fx=getf(x); int fy=getf(y);
merge(fx,fy);
}
else{
int x; x=read();
if(val[x]==-1)puts("-1");
else{
int fx=getf(x);
printf("%d\n",val[fx]); pop(fx);
}
}
}
}
模板 可并堆【洛谷P3377】 【模板】左偏树(可并堆)的更多相关文章
- 洛谷 - P1552 - 派遣 - 左偏树 - 并查集
首先把这个树建出来,然后每一次操作,只能选中一棵子树.对于树根,他的领导力水平是确定的,然后他更新答案的情况就是把他子树内薪水最少的若干个弄出来. 问题在于怎么知道一棵子树内薪水最少的若干个分别是谁. ...
- [note]左偏树(可并堆)
左偏树(可并堆)https://www.luogu.org/problemnew/show/P3377 题目描述 一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 ...
- Monkey King(左偏树 可并堆)
我们知道如果要我们给一个序列排序,按照某种大小顺序关系,我们很容易想到优先队列,的确很方便,但是优先队列也有解决不了的问题,当题目要求你把两个优先队列合并的时候,这就实现不了了 优先队列只有插入 删除 ...
- bzoj2809 [Apio2012]dispatching——左偏树(可并堆)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...
- 洛谷 P3377 模板左偏树
题目:https://www.luogu.org/problemnew/show/P3377 左偏树的模板题: 加深了我对空 merge 的理解: 结构体的编号就是原序列的位置. 代码如下: #inc ...
- [luogu3377][左偏树(可并堆)]
题目链接 思路 左偏树的模板题,参考左偏树学习笔记 对于这道题我是用一个并查集维护出了哪些点是在同一棵树上,也可以直接log的往上跳寻找根节点 代码 #include<cstdio> #i ...
- HDU3031 To Be Or Not To Be 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU3031 题意概括 喜羊羊和灰太狼要比赛. 有R次比赛. 对于每次比赛,首先输入n,m,n表示喜羊羊和灰 ...
- HDU5818 Joint Stacks 左偏树,可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU5818 题意概括 有两个栈,有3种操作. 第一种是往其中一个栈加入一个数: 第二种是取出其中一个栈的顶 ...
- BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆
https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...
- BZOJ 5494: [2019省队联测]春节十二响 (左偏树 可并堆)
题意 略 分析 稍微yy一下可以感觉就是一个不同子树合并堆,然后考场上写了一发左偏树,以为100分美滋滋.然而发现自己傻逼了,两个堆一一对应合并后剩下的一坨直接一次合并进去就行了.然鹅我这个sb把所有 ...
随机推荐
- mybatis 学习四(下) SQL语句映射文件增删改查、参数、缓存
2.2 select 一个select 元素非常简单.例如: <!-- 查询学生,根据id --> <select id="getStudent" paramet ...
- C Primer Plus学习笔记(四)- 运算符、表达式和语句
基本运算符 赋值运算符:= 在C语言中,=不是“相等”,而是赋值运算符,把左边的值赋给右边的变量 a = 2018; //把值2018赋给变量a 赋值表达式语句的目的是把值储存到内存位置上,用于储存值 ...
- 2016.4.6 WinForm显示PDF两种方法
1.最直接的方法,添加webbrowser控件 webb.Url = new Uri(path);可显示pdf控件. 如果需要在打开时跳转到某页,可用在路径后直接加#page=,例如webb.Url ...
- Android开发国际化
安卓中,国际化十分简单. 其实就是文件夹的问题.一般我们分两种情况. 一是app根据系统语言调用对应的资源文件夹,二是在app里面根据用户的需求来更改语言.前者比较简单,只需求创建对应国家的strin ...
- Android ListView 设置
android:minHeight="80dip"//设置每一条的高度 android:divider="@null" //设置默认的分割线不显示 androi ...
- TextView下划线,部分文字并响应点击事件(SpannableString)
TextView useInfo = (TextView) findViewById(R.id.info); useInfo.setText("开始即表示您同意遵守"); Stri ...
- android viewpage解决嵌套
子viewpage 自定义 写法一: public class ChildViewPager extends ViewPager{ /** 触摸时按下的点 **/ PointF downP = new ...
- Sequelize框架:
1.安装mysql支持: npm install mysql --save-dev 2.安装sequelize npm install sequelize --save-dev 3.创建ORM对象 v ...
- 关于Java继承体系中this的表示关系
Java的继承体系中,因为有重写的概念,所以说this在子父类之间的调用到底是谁的方法,或者成员属性,的问题是一个值得思考的问题; 先说结论:如果在测试类中调用的是子父类同名的成员属性,这个this. ...
- RTX这种东西究竟有什么价值?
我在第一家公司工作的时候,同事沟通用的就是RTX,第一感觉就是这么简单的软件也能卖钱? 这种东西有啥价值啊?不就是个没广告蓝色UI的qq吗? 还是那句话,当你已经习惯了一个东西之后,你不会感觉到他的价 ...