PERIODNI - Periodni 题解 & 笛卡尔树讲解 & 树状背包讲解
PERIODNI - Periodni 题解 & 笛卡尔树讲解 & 树状背包讲解
前置知识笛卡尔树
笛卡尔树每个节点具有标号和
可以证明,给你标号和
构造笛卡尔树
这里提供一种最优秀的 O(n) 做法。
第一步,如果
设当前节点为
例如,我们现在插入一个
现在这个右链就变成了
一直进行这样的操作就可以了。
但如果真的直接建树的话复杂度期望 (虽然可以过这个题)
所以我们用单调栈模拟实现。
单调栈实现
我们单调栈里面装的东西就是模拟这个右链。
当进入一个节点 a
-
令这个节点在栈中弹出的最后一个节点是 x ,那么 a 的左儿子为 x。
-
令这个节点在栈中的下面一个的节点是 y ,那么 y 的右儿子为 a。
可以结合下面图和上面的构造理解一下。
代码
void input(){
cin>>n>>m;
for(int i = 1; i <= n; ++i){
cin>>v[i];
while(top && s[top].v > v[i]){
--top;
if((!top) || (top && s[top].v <= v[i])){
tr[i].ls = s[top + 1].num;
}
}
if(top)tr[s[top].num].rs = i;
s[++top] = (node){i,v[i]};
}
for(int i = 1;i <= n; ++i){
jl[tr[i].ls] = 1;
jl[tr[i].rs] = 1;
}
for(int i = 1;i <= n; ++i){
if(!jl[i]) rt = i;
}
}
题目
[题面](PERIODNI - Periodni - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
解析
建模
我们把这个奇怪的图形看出几个矩形拼接而成,把每个矩形标号。

我们用每个矩形最矮的那一列来代表这个矩形
例如矩形 B 由 1,2 列构成,最矮的是 2 列,用 2 代替,类似的 D 用 4 来代替。
就变成了:

这像是一个树的结构,把他画出来看看。

把当前行的高度作为
首先,儿子节点的高度一定比父亲节点高,
按照左边左儿子,右边右儿子的规律建的树,一定满足二叉搜索树的性质。
容易观察到两个性质:
-
某矩阵所代表
和 的高度差就是矩阵的长度。 -
以
为根的子树大小就是矩阵的宽度。
当时我有这样的疑惑,如果树长这样有好像有 3 个儿子,阁下该如何应对。
我们把这个笛卡尔树画出来。

惊奇的发现它还是满足上面说的性质。
直接建树就行了。
树上背包
我们用树上背包 dp 。设
方程
最后还要计算当前矩形放数字的方案数。
总的来说,先把左儿子放入更新,再把右儿子放入更新,最后用自己更新。
这是什么意思?

例子:假设现在我们考虑到 x,x 左儿子放 0,1,2 个,x 右儿子放 0,1,2 个,那在 x 区域就可以放 0,1,2,3,4 个。
树上背包的思想和背包很像,其实他省略了一维 k 表示当前考虑了
的儿子节点得到的结果,就像背包中我们省略了一维当前考虑了 的物品。
那么如果当前矩阵是
选 k 行 k 列,然后排列,显然:
一定记住倒序枚举,省去了子树一维,注意枚举边界。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!