八月四,爆零日
\(\sf Rainybunny\):“我今天真的感觉到了,几天不写代码就写不来了。”
\(\sf OneInDark\):“我不一样,我从来都写不来代码。”
今天这场爆零了。\(T1\) 爆零,\(T3\) 不会,\(T2\) 写了个伪做法,\(n=7\) 的随机数据一组就出锅,所以爆零是理所当然的。只不过测试数据水的离谱。
越是爆零,越不想补题。就像越是自己不拥有的东西,越想撮合别人。——我想要 \(\sf yspm\) 和 \(\sf zero4338\) 的情头徽章(超大声)!
我焯,怎么是三道紫题!三道紫题爆零,\(\sf OneInDark\) 什么水平?
补题都感觉害臊,算了不补了。
《COCI2020-2021#2 Svjetlo》
不难发现移动是跟子树挂钩的。因此有个自然的想法是,设 \(\tt dp\) 状态为 \(f(x,0/1,0/1)\) 表示从 \(x\) 出发,只在子树内移动使得子树内除了 \(x\) 都被点亮,最后是否走回 \(x\) 以及 \(x\) 的明暗状态。
容易转移,因为每个子树只会进入一次。记得判断全 \(1\) 子树。然后换根,因为转移是矩阵形式。常数确实大。
不过正解是讨论路径有几个端点在子树内,没有定位端点(于当前节点上),非常高明啊。
《COCI2020-2021#1 3D Histogram》
起先想在右端点移动时维护左端点答案,感觉难搞啊。
不妨从简单想起。即使 \(b_i=1\) 上面的做法都挺不好搞;最好的做法是枚举 \(\min\{a_i\}\) 。
所以我们枚举 \(\min\{a_i\}\),问题转化为区间内最大 \(\Delta x\cdot\min\{b_i\}\) 。
考虑在 \(\{b\}\) 的笛卡尔树上定位该区间,用 \(\tt zkw\) 线段树的方式,显然在 \(l,r\) 到其 \(lca\) 这两条链上的点作为 \(\min\{b_i\}\) 时,可用区间受 \(l\) 或 \(r\) 限制(在区间外的,也也可套用该式计算,因为其值必为负数),而内部的点不受限制。只有 \(lca\) 单点同时受 \(l,r\) 限制,这个 \(\mathcal O(1)\) 算出来就好。
受限制的点的贡献是 \(b_i(r{-}l_i)\),其中 \(r\) 是询问值(是变量)。这是一次函数。不受限制的点的贡献是定值,这个较简单;先解决树链上的一次函数最值问题。
有个细节是,越深的点的斜率 \(b_i\) 越大。那我们在树上 \(\rm dfs\) 时维护可回退凸包,插入是容易的。注:新插入的直线更深,这是更容易被包含在询问范围内的,因此弹掉被覆盖的直线是合理的。
递归到需要询问的树链的下端点时,询问之。若该点对应凸包直线在询问区间内,答案即得。否则应使用最靠上的直线。因为插入直线是从左到右、斜率递增的。
而定值(不受限制的点的贡献)相当于斜率为 \(0\) 的直线,同理可维护。相当于是可回退单调队列。
所以我们 \(\mathcal O(n\log n)\) 得到了所有询问的答案。定位 \(lca\) 等使用 \(\textit{RMQ}\) 即可,总复杂度 \(\mathcal O(n\log n)\) 。这在 \(b_i=1\) 的 \(\mathcal O(n)\) 计算基础上添了个 \(\log n\),似乎也有道理。
《COCI2020-2021#3 Specijacija》
\(\rm DS\) 的目标在于 给计算机一个可维护的结构 而不是自己手算任何东西。我曾试图解节点在某层的编号。
注意到 \(lca\) 几乎总是分岔点,将分岔点的虚树建出来即可。
求最近的分岔点,可以自顶向下,可持久化平衡树就维护出来了。
为了代码实现的方便,不妨用可持久化线段树(可持久化数组)自底向上维护。修改时,使用“先赋值再复制”的方法,就可以把前面的所有版本统一赋值了。
找到分岔点之后的事情是平凡的。经 \(\sf Rainybunny\) 提醒,最好把自己是左儿子还是右儿子存下来。
如果这篇文章对你有帮助,那么作者是:OneInDark,原文在:https://www.cnblogs.com/OneInDark/p/16552474.html,否则我也不知道这是谁的文章。