八月四,爆零日

\(\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\) 提醒,最好把自己是左儿子还是右儿子存下来。

posted @ 2022-08-04 22:00  OneInDark  阅读(161)  评论(0编辑  收藏  举报