还是改不掉看到数数题和概期题就害怕的习惯。
不是所有的概期都要 dp
设能在 k 时刻内点燃第 i 棵树的区间是 [li,ri],那么显然,第 i 棵树被点燃的概率是 1−∏j=liri(1−aj)。把这些都加上就是了,可以很容易的做到 O(n2)。
观察到 li 和 ri 都是单调递增的,于是直接双指针做到 O(n)。
注意处理 ai=1 的情况,因为 0 没有逆元。
大样例一定要测
有显然的结论:a 中取的个数加上 b 中未取的个数等于 b 的总数。我们考虑把求解“取最大的 k 个 b”改成求解“取最小的 cntb−k 个 b”。
使用一颗权值线段树维护 a 和 b,我们在插入 a 的时候正常插入,在插入 b 的时候插入将要插入的树的相反数,答案就是 sumb 减去权值线段树里最大的 cntb 个数的和,时间复杂度 O(mlogV)。
但是大家都是 O(mlog2V) 过的。。。出题人紧急加了一组 hack。。。
我们有朴素的 dp 方程。因为如果一颗子树内还没有染完色,那么剩下的叶子节点的 cu 一定相同。所以我们可以设 dpu,x 表示 u 的子树内还没有染完色,还需要一个染色为 x 的祖先的方案数。而 dpu,0 表示这个子树已经染完色了,不用再染了。
转移方程如下:
dpu,xdpu,0=v∈sonu∏(dpv,0+dpv,0)−v∈sonu∏dpv,0=(m+1)v∈sonu∏dpv,0+i=1∑mdpu,i也是很好理解啊。边界就是对于每个叶子:dpu,0=dpu,cu=1。这个转移方程可以很容易的做到 O(n2),考虑如何优化。
钱神讲了一个神秘的优化方法:重剖优化 dp。我们每次先处理 u 的重儿子,让 dpu 直接继承 dpsonu 的值。然后每次暴力合并剩下的轻儿子。
但是合并的时候有许多的细节。我们看到,dpv,0 要对 ∀x∈[1,m] dpu,x 做出贡献,但是如果每次暴力让 dpu,x 去乘上每个 dpv,0 的话,时间复杂度原地退化。所以我们对于每个 u 记录一个 tagu,表示这个 u 里的每个 dpu,x 都要乘上一个 tagu。当然这个 tagu 也是直接从重儿子继承的啊。维护 tagu 只需要在每次转移 v 的时候,让 tagu 乘上 dpv,0×tagv 就是了。
时间复杂度 O(nlogn),因为重链只剖的出来 O(logn) 层。
后日谈
什么时候能看到计数题和概期题不害怕呢?
日记
周三 10月 15 2025 725 字 · 3 分钟