那么用 KMP 解决单模式串问题启示我们使用 AC 自动机解决多模式串问题,那么剩下的就顺其自然了,首先将所有串插入 AC 自动机,设 \mathrm{tag}_p 表示在节点 p 所代表的串的后缀中模板串的数量的奇偶性,然后在算 \mathrm{fail} 的同时把所有节点的 \mathrm{tag} 也一起算出来,运用 tag 来支持我们的 dp,转移方程由于 AC 自动机认子不认父的结构,写成枚举起点转移别人的方式会更加简单,直接根据 AC 自动机的 trie 图转移就好了,等所有都转移好了再将满足 \mathrm{tag}_p=1 的 p 对应的 g 全部取反,实现难度不大,时间复杂度 \mathcal O\left(nk\sum|g_i|\right)。
\rm subtask\ 5,6
到这里就是正解了,我们发现我们现在唯一的障碍就是 t>1,但是我们在前面讲 \rm subtask\ 3 的时候讲到我们分裂得到的每个细胞是互相独立的,那么 t 影响的实际上就是数列中每个数变成别的数的概率,我们只要知道 t 个时刻后每个数变成另一个数的概率直接套用 \rm subtask\ 4 的做法就好了,我们发现可以对给定的 P 矩阵做矩阵快速幂,P 矩阵的 t 次方即我们所求,这样就做完了,时间复杂度 \mathcal O\left(k^3\log t+nk\sum|g_i|\right)。
具体代码实现方面,整份代码本来是数据点分治,\rm subtask\ 1 部分 n 与 \sum|g_i| 较大,直接用后面的做法会 TLE,要特殊处理,而后面 \rm subtask\ 3 的 k 较大,在矩阵快速幂过程中 k^3 与单位矩阵相乘一次会直接 TLE,但是这些都可以解决,我们一定要建出 AC 自动机,且与后面的 AC 自动机一致,所以 \rm subtask\ 1 可以在建出 AC 自动机后几行解决,\rm subtask\ 3 实际我们在转移过程中有用的可以压缩成 1/2,将所有不是 1 的转移压缩到 2 上,矩阵压缩成 k\times 2 的,虽然不能矩阵幂,但是矩阵乘一次是可以接受的,就可以减少很大一部分特判,剩下的部分直接和正解部分合并就好了,代码并不麻烦。