码迷,mamicode.com
首页 > 其他好文 > 详细

笛卡尔树

时间:2020-09-08 20:42:17      阅读:37      评论:0      收藏:0      [点我收藏+]

标签:在线   rmq   树形结构   一段   ++i   左右   时间   llb   mat   

闲的没事翻新题,突然想起笛卡尔树还没学,于是写了写笛卡尔树的模板题。

题意

  • 给一个排列p1~pn,i号点权值为pi,要求建一棵以编号为关键字的二叉搜索树(中序序列为1~n),且以权值为关键字的小根堆。

  • n <= 1e7

思路分析

难度在于O(n)建树。但既然编号是连续的,那么我们就每次使劲往右插即可。因此我们要维护一条从根节点一直向右的链

又因为要维护小根堆性质,每次在链上找到一对相邻点,使得父亲权值大于它,且儿子权值小于它。把儿子设为自己的左儿子,并把自己设为父亲的右儿子即可。

Code:

for (register int i = 1; i <= n; ++i) {
	while (top && val[sta[top]] > val[i])	ls[i] = sta[top--];
	if (top)	rs[sta[top]] = i;
	sta[++top] = i;
}

然而并不知道它有什么用。

一个不那么显然的性质

其实还是挺显然的

笛卡尔树上每个节点的子树中的编号集合一定是一段连续的区间,不过一段连续的区间却不一定是一个连通块。

实用版建树:

维护每个点的子树编号区间(这个点一定是区间中的权值的最值点),找出区间中该点左右的最值点,该点向那两个点连边,然后递归子问题。

例题

SP3734 PERIODNI - Periodni

(大概是最经典的笛卡尔树题了)

给个直方图,问放 \(k\) 个不在同一行同一列的点的方案数。

我们发现直方图其实还可以横着划分,划分成一个个方块(见 lhm_大佬的题解),然后会出现树形结构(类似树形依赖关系),用类似树形背包的组合计数DP解决即可。

技术图片

这个树形结构其实就是笛卡尔树。

可见,笛卡尔树擅长把序列最值“瓶颈”问题转化为树上的问题。

P3246 [HNOI2016]序列

这题似乎是想用笛卡尔树优化rmq的一个log,但似乎那个题解被 hack 了。

题解在这

强制在线1e7询问的加强版(在鸽)

P5044 [IOI2018] meetings 会议

看不懂题解+看不懂题解代码+不会线段树,可能还要鸽一段时间。

lsr大佬的题解

不知道为啥我刚要做,lsr大佬就写好题解了,然后我还看不懂qaq

2020.8.28 Update:

写完了。感谢 ywy 学长的讲解!

笛卡尔树上 DP,用线段树来优化。不过用到笛卡尔树的一个套路:按照最大值把询问区间拆成两半,这样的话每一半都会有一侧是完整的,利用这个性质方便解题。

jzp 的题解

笛卡尔树

标签:在线   rmq   树形结构   一段   ++i   左右   时间   llb   mat   

原文地址:https://www.cnblogs.com/JiaZP/p/13576902.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!