首先想到的肯定是动态加点,关键是怎么算贡献🤔
如果只固定了 x , y x,y x,y,发现还不能算贡献。发现可以考虑差分,也就是说计算最小值 ≥ x \ge x ≥x的概率之和。
这样就可以树 D P DP DP了。这样修改一个点的状态就要改变所有祖先节点的 D P DP DP值。
首先要做过这道题 【模板】“动态 DP”&动态树分治 。虽然我之前做过但是现在已经忘完了😭
只要能够写成 广义矩阵乘法 的形式,我们就能用这个方法去维护。
这道题目的树 D P DP DP显然是线性变换的形式,可以考虑写成矩阵,这样用树链剖分做到 O ( n log 2 n ) O(n\log^2 n) O(nlog2n)。
一般来讲,树链剖分可以用 全局平衡二叉树 来代替。这是一个静态的类似于 L C T LCT LCT的数据结构,树高是严格 O ( log n ) O(\log n) O(logn)的。
让我们想想动态 D P DP DP的本质是在维护什么。发现就是在维护重链上转移矩阵的乘积。
但是还要对每个节点求和😰,虽说可以一并写进矩阵里面,但是这样就是 3 × 3 3\times 3 3×3的大小了,所以必须手算矩阵乘法😅
所以可能还要做过这道题 [NOIP2022] 比赛 。
复杂度 O ( n log n ) O(n\log n) O(nlogn)。
考虑哪些点会被修改,发现这等价于 转移矩阵会发生变化的节点 ,那么就等价于 若干个 单点修改,所以直接跳父亲就好啦😃
但是还要维护一个点是不是灰点,以及儿子节点是灰点的数目😰 。所以如果一个点变成了灰点,并且父亲跟它 在同一条重链上 ,那么父亲的转移矩阵 要暴力计算 ,并视为单点修改来处理😅 。如果父亲跟它不在同一条重链上,那好像复杂度就不对了😅。所以难道还要三度化😰
发现好像把灰点和白点的和分开维护就可以 O ( 1 ) O(1) O(1)修改了。但是我已经不想写了😅