最值分治生成树

全文5368k。

额...只不过是因为刷题赛里出现了两道笛卡尔树,所以特意从新拿出来审视了一遍。

今天晚上要 Hello 2023,所以可能更没有时间补那道多项式了qwq。

至于线段树,那又只能明天学了/bai

笛卡尔树#

定义:满足堆性质的二叉搜索树,也就是常用的 Treap。

性质:中序遍历是原序列;父亲的权值比儿子小(以小根堆为例)

如果这是一个全序关系,那么这个笛卡尔树是唯一的。

建树:

笛卡尔树可以通过单调栈 O(n) 构建。具体伪代码如下:

例 1 洛谷P5854【模板】笛卡尔树

https://www.luogu.com.cn/problem/P5854

给定一个 1n 的排列 p,构建其笛卡尔树。

模板题。

随机笛卡尔树的树高是 O(logn) 的,其实是调和级数。

例 2 AGC028B Removing Blocks

https://www.luogu.com.cn/problem/AT_agc028_b

N 个数,每个数有一个全会 Ai。进行 N 次操作,每次操作选择一个数删掉,代价是所有和其连通的没被删掉的数的权值和,求所有 N! 种删数方法的代价和。

考虑对删除序列建小根堆笛卡尔树,那么每个点的贡献即为子树中 a 的和。转换为每个点贡献是 ai×depi,那么所求即为期望深度。根据前几天平衡树的那个证明,可以发现这个期望深度应该是 j=1x11xj+1+j=x+1n1jx+1+1=H(i)+H(ni+1)1H(n)=i=1n1n。这样就可以 O(n) 计算了。

例 3 RMQ Similar Sequence

Petrozavodsk Summer 2018. Day 4. Xi Lin Contest

http://qoj.ac/problem/242

给定序列 A,序列 B 的每个元素在 [0,1] 之内随机(实数),B 的价值是,当 B 和 A 的笛卡尔树同构时为元素和,否则是 0。求 B 的价值的期望。定义值相同时排在前面的更大。

由于是在实数中随机,所以两个数相等的概率是 0,那么可以假设 B 是一个排列,一个排列与 A 的笛卡尔树同构,其实就是拓扑序相同,那么 B 的个数就可以算出了。即为 n!szi[0,1] 中随机一个数的期望是 12,所以 n 个数的和的期望就是 n2 用这个值去乘上排列的个数即可得到答案。
code

有关深度的计数,以及一些和深度有关的结论。

例 4 CF1220F Gardener Alex

https://codeforces.com/problemset/problem/1220/F

给定长度为 n 的排列,可以将前 i 个元素移动到最后,所有可能的排列的小根笛卡尔树的最大深度的最小值。

考虑对于两个位置 i,j,什么时候 ji 的祖先,也就是 minmin(i,j)kmax(i,j)pk=pj 的时候。那么这道题,我们就可以模拟移动的过程,每次找到第一个大于他的位置,然后前面的位置都可能被贡献到,用一个线段树来维护即可。code

例 5 USACO19DEC Tree Depth P

https://www.luogu.com.cn/problem/P5853

对每个数求出所有逆序对数是 k 的长度为 n 的排列的笛卡尔树上的深度和,深度定义为根到它的点数。

有一个算逆序对的方法,是按顺序从小到大加入,那么这样每次可以贡献的逆序对数刚好从 0i,那么就相当于卷上一个 j=0i1xj 这样的 OGF。最后答案就是 [xk]i=1n1xi1x。那么回到这道题,根据上一题的结论,考虑 u,v 两个点什么时候 vu 的祖先,那么就是 v[min(u,v),max(u,v)] 这个区间中最小的数。

u<v 的时候,按照 u,u+1,,v,u1,,2,1,v+1,v+2,,n 的顺序填数,否则我们按照 u,u1,,v,u+1,u+2,,n1,n,v1,v2,,2,1 的顺序填数,容易发现这样的效果和之前是一样的,唯一不同的是 v 这个位置的逆序对数是确定的,不能算进贡献。u<v 时多贡献的逆序对数是 vu,否则是 0,然后 |uv| 这个 OGF 也不用贡献进答案。

那么就有了一个做法,枚举所有 |uv|,用多项式除法(回退背包),把这一项的贡献消除,然后枚举所有 u,找到这一项 v 的贡献。

暴力实现多项式乘法+除法,总的复杂度是 O(n3)code

例 6 HDU6854 Kcats

前缀 i 的单调栈大小,即 i 号节点在全局的笛卡尔树上对应的位置的所有在左边的祖先个数,考虑dp,设 f[l][r][d] 代表区间 [l,r] 的笛卡尔树的根的左边祖先有 d 个的方案数。

转移即枚举最小值的位置 p,然后从 f[l][p1][d]×f[p+1][r][d]×(rlpl) 转移。

复杂度 O(n4),比较卡常,建议参考代码的卡常技巧。code

u 为根的笛卡尔树,代表一段区间,区间最小值是 u 上的值。区间 [a,b] 的最小值是 lca(a,b) 上的值。所以当遇到区间 rmq 作为要求/条件/所求的时候不妨想一想笛卡尔树。

例 7 Periodni

https://www.luogu.com.cn/problem/SP3734

给定一个网格图,第 i 高度为 ai。往网格里填 k 个数,同一列不能填两个数,同一行不能填两个数。如果中间有断开则不算同一行,问方案数。

要求即为对于同一行的数,放在高度 h 的位置,那么 minijai<h。看到这个区间最小值想到小根堆笛卡尔树,建出笛卡尔树后就是一个树形背包问题,然后转换为在 n×m 的矩阵中选 k 个数的方案数,即为 k!×(nk)(mk)。于是就可以直接dp了,复杂度 O(nk2)

例 8 CF1580D Subsequence

https://codeforces.com/contest/1580/problem/D

将式子化以下,(m1)abi2i=1mj=i+1mminbikbjak
后面那个东西可以用笛卡尔树转换为 alca(bi,bj),然后我们定义边权为 aiafai
那么即可转换为选 m 个点使得其距离和最大,直接树形背包即可。

例 9 ZJOI2012 小蓝的好友

https://www.luogu.com.cn/problem/P2611

有一个 R×C 的图,图上有 n 个随机的点,询问有多少矩形包含至少一个点。1R,C4×104,1N105

转换为对不包含任意一个点的矩形计数,考虑枚举矩形的底,求出每一列距离这一行最近的点的高度,记为 hi,然后转换为计数 lrminlkrhk。这个可以用笛卡尔树来维护,即维护 hi×(szlsi+1)×(szrsi+1) 的和。还要可以单点修改,用 treap 维护,由于数据随机所以复杂度正确。

例 10 JOISC2020 星座 3

https://www.luogu.com.cn/problem/P7219

本题有一个很妙的贪心做法,但是和本文无关,所以就不再多做介绍。

两个星星是否可以组成一个星座,显然和他们之间的最高的小船有关,那看到这个自然想到笛卡尔树。考虑 dp,转换为求最大保留多少,如何消除后效性。容易发现最大值上方的部分只能保留一个,所以设 f[u][h] 代表 u 子树内最大星星高度是 h。暴力转移很显然,考虑如何优化。发现我们需要的时候区间加,对应位置合并求 max,以及单点修改,于是可以线段树合并维护,树上线段树合并时空复杂度均为 O(nlogn)

笛卡尔树本质是最值分治的结构

其实就是笛卡尔树的结构,找到最值,然后分成两边递归。

例 11 P4755 Beautiful Pair

https://www.luogu.com.cn/problem/P4755

有个数列 a,当一个数对 (i,j) 满足 aiaj 的积不大于 maxk=ijak,这个数对是美丽的。请你求出美丽的数对的数量。

建出大根笛卡尔树,然后预处理出子树的区间,启发式分治,每次只遍历小的那一边,然后处理成区间询问。离线扫描线,然后离线扫描线即可。复杂度可以做到 O(nlog2nloglogn)code

例 12 IOI2018 meetings 会议

https://www.luogu.com.cn/problem/P5044

f[l][r] 代表区间 [l,r] 的答案。设 x[l,r][l,r] 中最大的元素的位置。那么可以如此转移 f[l,r]=min(f[l,x=1]+(rx+1)×hx,f[x+1,r]+(xl+1)×hx)

考虑建出笛卡尔树,那么对于 x 的子树,可以来维护对于区间内的 dp 值。考虑维护 f[l,x1]f[x+1,r],如果这些值被维护出来后直接枚举询问就好了。假设 y 的父亲是 x,不妨设 xy,那么我们就是要维护 f[l,y1],lsub(x)

那么根据转移方程 f[l,y1]=min(f[l,x1]+hx×(yx),f[x+1,y1]+hx×(xl+1)),考虑用线段树来优化。首先先给第一部分区间加。而这个 f 显然是单调的,后者是一条直线,找到交点之后就可以区间赋值了,注意线段树pushdown的顺序,应该先赋值再加。对于右半边的部分直接继承就好啦。

其实也就是这个dp是一个分治信息,可以快速维护。最后的复杂度为 O((n+q)logn)

笛卡尔树合并

可以参考之前2022.12.30的闲话。

posted @   Semsue  阅读(99)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
Title
点击右上角即可分享
微信分享提示
主题色彩