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

左偏树+并查集

左偏树维护两个可合并的堆,并查集维护两个堆元素合并后可以找到正确的树根。

关键点在于删除一个堆的堆根的时候,需要把原来堆根的父指针指向新的堆根。这样并查集的性质就不会被破坏了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; int solve(); int main() {
#ifdef Yinku
freopen("Yinku.in","r",stdin);
#endif // Yinku
solve();
} const int MAXN=100005;
int tot,v[MAXN],l[MAXN],r[MAXN],d[MAXN],f[MAXN];
//这其实是一片左偏树森林,用处不大
struct Leftist_Tree{
int Merge(int x,int y){
//将两棵左偏树,返回他们的新根
//当其中一棵是空树,直接返回另一棵
if(!x||!y)
return x+y;
//此处符号决定是最小堆还是最大堆
if(v[x]>v[y]||(v[x]==v[y]&&x>y))
swap(x,y);
//维持x不比y大,相等则把小的那个作为根
//把大数y插入小数x的右子树,所以是最小堆
r[x]=Merge(r[x],y);
if(r[x]==x)
r[x]=0;
//保证左子树比右子树高
//新的右子树的根的父亲是x,不需要可以删除
f[r[x]]=x;
if(d[l[x]]<d[r[x]])
swap(l[x],r[x]);
d[x]=d[r[x]]+1; return x;
}
int Build(int x){
//新建一棵只有x的左偏树,返回他的编号
tot++;
v[tot]=x;
//新树的节点的父亲为他本身,不需要可以删除
f[tot]=tot;
l[tot]=r[tot]=d[tot]=0;
return tot;
}
int Push(int x,int y){
//向编号为x的左偏树插入值为y的节点,其实就是新建只有y的左偏树然后合并
return Merge(x,Build(y));
}
int Top(int x){
//直接返回编号为x的左偏树的堆顶
return v[Get_root(x)];
}
int Get_root(int x){
//查找编号为x的节点所在的左偏树的根的序号,不需要可以删除
int r=x;
while(f[r]!=r)
r=f[r];
//路径压缩,直接指向他们的根
int k;
while(f[x]!=r){
k=f[x];
f[x]=r;
x=k;
}
return r;
}
int Pop(int x){
//将两个子树合并,相当于删除了堆顶
//return Merge(l[x],r[x]);
//当需要保留查询编号为x的节点在哪个子树时,不能够把堆顶丢掉
//把编号为x的元素删除
v[x]=-1;
//根x被删除,从x反过来指向他们的孩子就可以了
int rt=Merge(l[x],r[x]);
f[x]=f[l[x]]=f[r[x]]=rt;
return rt;
}
}; int solve() {
int n,m;
scanf("%d%d",&n,&m);
//printf("n,m=%d,%d\n",n,m);
Leftist_Tree lt;
f[0]=0;
v[0]=-1;
tot=0;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
//printf("x=%d\n",x);
lt.Push(i,x);
/*for(int j=1;j<=tot;j++){
printf("%d ",v[j]);
}
printf("\n");*/
}
for(int i=1;i<=m;i++){
int z,x,y;
scanf("%d",&z);
//printf("z=%d\n",z);
if(z==1){
scanf("%d%d",&x,&y);
//printf("x=%d y=%d\n",x,y);
if(v[x]==-1||v[y]==-1)
continue;
lt.Merge(lt.Get_root(x),lt.Get_root(y));
}
else{
scanf("%d",&x);
if(v[x]==-1){
printf("-1\n");
continue;
}
//printf("x=%d\n",x);
int fx=lt.Get_root(x);
printf("%d\n",lt.Top(fx));
lt.Pop(fx);
}
}
return 0;
}

洛谷 - P3377 - 【模板】左偏树(可并堆) - 左偏树 - 并查集的更多相关文章

  1. 洛谷 P3377 模板左偏树

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

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

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

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

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

  4. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  5. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  6. 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]

    题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...

  7. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  8. 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】

    题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...

  9. BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html 题目传送门 - LOJ#2512 题目传送门 - 洛谷P4458 题目传送门 - BZOJ ...

随机推荐

  1. CSS入门学习

    一.What? CSS的全称是CascadingStyle Sheet,汉语意思是"级联样式表".通常又称为"风格样式表(StyleSheet)".它是用来进行 ...

  2. Xcode 6 IDE

    本文转载至 http://www.cocoachina.com/ios/20140823/9442.html     (via:苹果开发者中心) Xcode IDE 是 Apple 开发体验的核心.X ...

  3. 用Darwin开发RTSP级联服务器(拉模式转发)(附源码)

    源码下载地址:https://github.com/EasyDarwin orwww.easydarwin.org 在博客 在Darwin进行实时视频转发的两种模式 中,我们描述了流媒体服务器对源端音 ...

  4. DuiLib笔记之Control常用属性

    name 指定控件名称,同一窗口内必须唯一,类型:STRING float 用于指定控件是否使用绝对定位,或设置FloatPercent,类型:BOOL,默认值为false,格式:float=&quo ...

  5. DIV+CSS常见问题的14条原因分析

    当你在一个浏览器里面做好,在其他浏览器里面却完全不是那么回事情.  很多时候,我们就只是去修补下,或者利用各个浏览器对代码支持的不一致,进行针对各个浏览器进行不同的定义.  其实浏览器的不兼容,我们往 ...

  6. 【LeetCode】Search in Rotated Sorted Array II(转)

    原文链接 http://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ http://blog.csdn.net/linhuan ...

  7. [IR课程笔记]概率检索模型

    几个符号意义: R:相关文档集 NR:不相关文档集 q:用户查询 dj:文档j 1/0风险情况 PRP(probability ranking principle):概率排序原理,利用概率模型来估计每 ...

  8. XMPP学习笔记 -- RFC 6120

    XMPP - Extensible Messaging and Presence Protocol 1. 中文版3920 http://wiki.jabbercn.org/RFC3920 2. 大部分 ...

  9. Javascript高级程序设计笔记(很重要尤其是对象的设计模式与继承)

    var obj = {'a':'a'}; var fun = function (){} console.log(typeof obj);//object console.log(typeof fun ...

  10. python基础知识踩点

    1.注释 在python中,注释是以任何存在于#右侧的文字,其主要作用是写给程序读者看的笔记. 例如 单行注释 >>print("hello world") #这是一个 ...