• [SDOI2017]切树游戏


    CLIII.[SDOI2017]切树游戏

    \(f_{x,0,i}\) 表示 \(x\) 子树中,所有包含 \(x\) 且异或和为 \(i\) 的连通块数量,\(f_{x,1,i}\) 表示 \(x\) 子树中异或和为 \(i\) 的连通块数量。显然,有公式

    \[f_{x,1,i}=f_{x,0,i}+\sum\limits_{y\in\text{subtree}_x}f_{y,1,i} \]

    现在考虑 \(f_{x,0,i}\) 的转移。假如我们要合并 \(x\) 与某个儿子 \(y\) 的DP数组,则显然有公式

    \[f_{x,0,i}=\sum\limits_{j\operatorname{xor}k=i}f'_{x,0,j}\times(f_{y,0,k}+[k=0]) \]

    其中 \(f'\) 是老的 \(f\) 数组。

    发现这是异或卷积形式,可以FWT优化。

    但是我们发现,因为DP过程中全程要么在卷积,要么在做加法,对FWT后的数组作也是一样的。因此我们重新修改定义,将 \(f\) 数组全数修改为FWT后的数组。又因为 \(z^0\) 这个函数在FWT后会得到 \(\sum\limits_{i=0}^mz^i\),因此转移式变更为

    \[f_{x,1,i}=f_{x,0,i}+\sum\limits_{y\in\text{subtree}_x}f_{y,1,i} \]

    \[f_{x,0,i}=f'_{x,0,j}\times(f_{y,0,k}+1) \]

    直接硬DP,单次复杂度 \(O(nm)\)

    现在考虑轻重链剖分。设 \(g\) 表示仅考虑轻儿子时的答案。若只考虑 \(x\) 的一个重儿子 \(y\),则有

    \[f_{x,0}=g_{x,0}\times(f_{y,0}+1)=g_{x,0}f_{y,0}+g_{x,0} \]

    \[f_{x,1}=f_{x,0}+g_{x,1}+f_{y,1}=g_{x,0}f_{y,0}+g_{x,0}+g_{x,1}+f_{y,1} \]

    当然,这里的所有东西都是函数,连上面的 \(1\) 都不例外,指的是元素全为 \(1\) 的函数。

    同时,要留心一点常规 \(g\) 的转移:

    \[g_{x,0}=\text{FWT}(z^{a_x})\prod\limits_{y\in\text{lightson}_x}(f_{y,0}+1) \]

    \[g_{x,1}=\sum\limits_{y\in\text{lightson}_x}f_{y,1} \]

    需要注意的是,叶节点的 \(g\) 数组应直接是其 \(f\) 数组,故对于叶子节点,有 \(g_{x,0}=g_{y,0}=\text{FWT}(z^{a_x})\)

    我们可以列出转移矩阵来:

    \[\begin{bmatrix}f_{y,0}\\f_{y,1}\\1\end{bmatrix}\begin{bmatrix}g_{x,0}&g_{x,0}&0\\0&1&0\\g_{x,0}&g_{x,0}+g_{x,1}&1\end{bmatrix}=\begin{bmatrix}f_{x,0}\\f_{x,1}\\1\end{bmatrix} \]

    \(3\times3\) 矩阵就有着 \(3^3\) 的常数,不好玩。但是,当我们计算两个上述矩阵的积后

    \[\begin{bmatrix}a_1&b_1&0\\0&1&0\\c_1&d_1&1\end{bmatrix}\begin{bmatrix}a_2&b_2&0\\0&1&0\\c_2&d_2&1\end{bmatrix}=\begin{bmatrix}a_1a_2&b_1+a_1b_2&0\\0&1&0\\a_2c_1+c_2&b_2c_1+d_1+d_2&1\end{bmatrix} \]

    发现矩阵的积不会影响其余位置的取值。

    因此我们考虑只维护 \(a,b,c,d\) 四个位置的值,即可压缩矩阵为 \(2\times2\)

    于是现在的转移矩阵就压缩为

    \[\begin{bmatrix}a_1&b_1\\c_1&d_1\end{bmatrix}\begin{bmatrix}a_2&b_2\\c_2&d_2\end{bmatrix}=\begin{bmatrix}a_1a_2&b_1+a_1b_2\\a_2c_1+c_2&b_2c_1+d_1+d_2\end{bmatrix} \]

    同时,其存在单位元

    \[\begin{bmatrix}1&0\\0&0\end{bmatrix} \]

    我们同时还要支持从链顶父亲的 \(g\) 数组中删掉一个 \(f\) 数组的操作。这样就需要支持除法。但是你不能保证FWT不会出现零。但我们可以维护每个位置的非零数之积是什么,再维护每个位置出现了多少零,这样分开处理,即可支持除法。

    代码先咕着

  • 相关阅读:
    Spring杂谈 | 什么是ObjectFactory?什么是ObjectProvider?
    一次相亲经历,我彻底搞懂了什么叫阻塞非阻塞,同步异步
    Spring杂谈 | 你真的了解泛型吗?从java的Type到Spring的ResolvableType
    Spring官网阅读(十二)ApplicationContext详解(中)
    Spring官网阅读(十一)ApplicationContext详细介绍(上)
    Spring官网阅读(十)Spring中Bean的生命周期(下)
    Spring官网阅读(九)Spring中Bean的生命周期(上)
    influxDB 0.9 C# 读写类
    使用HAProxy实现sql server读库的负载均衡
    influxdb基本操作
  • 原文地址:https://www.cnblogs.com/Troverld/p/14601773.html
Copyright © 2020-2023  润新知