2024.8 #6
T1. [AGC060F] Spanning Trees of Interval Graph
我们令 \(S = \sum C_{i,j}\)。
我们设两个矩阵 \(B_{i,j} = [[L_i,R_i] \cap [L_j,R_j]]\) 以及 \(A_{i,i} = \sum B_{i,j}\)。
那么根据矩阵树定理,我们知道生成树的数量就是 \(\det(A - B)\)。然而直接高斯消元复杂度是 \(O(S^3)\) 的,难以接受。我们需要考虑如何优化 \(A\)。
考虑矩阵行列式引理,我们需要构造出两个 \((S - 1) \times m\) 的矩阵 \(A,B\),使得 \(G = A \times B^T\),那么根据矩阵行列式引理:\(\det(D-G) = \det(I - B^TD^{-1}A)\det(D)\),其中 \(I\) 为单位矩阵。接下来的问题就变成了如何构造大小为 \((S - 1) \times m\) 的矩阵 \(A,B\)。
为了求出 \(A,B\) 后方便计算答案,我们令 \(m = 2 \times n - 1\)。
那么此时我们考虑用两个点来表示两个区间是否有交,不难发现其实就是相交的点数减相交的边数是否为 \(1\)。那么 \(F,G\) 的构造如下:
-
\(F_{i,2 \times j - 1} = G_{i,2 \times j - 1} = [j \in [L_i,R_i]]\)
-
\(F_{i,2 \times j} = -1 \times [[j,j + 1] \in [L_i,R_i]]\)
-
\(G_{i,2 \times j} = [[j,j + 1] \in [L_i,R_i]]\)
那么我们就可以直接利用高斯消元 \(\mathrm O(m^3)\) 求出行列式的值。
T2.HAOI 2017 字符串
我们先考虑如何判断两个字符串 \(a,b\) 相似。很明显,条件为 \(|a| = |b|\) 且 \(\text{LCP}(a,b) + \text{LCS}(a,b) + k \ge |a|\)。其实就相当于把 \(b\) 中一个长度为 \(k\) 的子串换成通配符后和 \(a\) 相等。
此时我们可以考虑容斥,对于每一个 \(p_i\),我们枚举长度为 \(k\) 和 \(k - 1\) 的区间换乘通配符,然后求出换完后的字符在 \(s\) 中的出现次数。然后通过一些计算就可以得出答案了。
具体的,我们对字符串的正串和反串建出一个 AC 自动机,并且记录文本串每一个每一个位置在 AC 自动机上的节点。
由于换成通配符之后,只剩下一个 \(\text{pre}\) 和一个 \(\text{suf}\),一个 \(j\) 对于答案有贡献的要求就是 \(s\) 中以 \(j\) 为开头长度为 \(|\text{pre}|\) 的子串等于 \(\text{pre}\),\(s\) 中以 \(j + |\text{pre}| + k\) 为开头,长度为 \(|\text{suf}|\) 的子串等于 \(\text{suf}\)。我们的任务就是求出这样的 \(j\) 的个数。
那么这个条件转移到树上就变成了 \(s\) 以 \(pos\) 为结尾的后缀在 AC 自动机上的节点在 fail 树上在 \(p_i\) 的前缀 \(j\) 在 AC 自动机上的节点子树之中。这是前缀的情况,后缀的情况同理。
那么我们只需要把 在某个点的子树内 这个限制转化为 DFS 序在某个区间内 这个限制,这样我们就可以使用二维数点来解决了。