1 条题解
-
0
热身问题
首先考虑一个更简单的相关问题。
设 为题目中表示城市与道路的图, 为其邻接矩阵。
假设我们不是要计算特殊旅行,而是要计算长度为 且起点与终点相同的普通旅行的数量。引理 1
对于任意 , 的第 个元素 等于从 出发、到 结束的长度为 的旅行的数量。
证明
当 时,由邻接矩阵的定义显然成立。
假设引理对 成立,考虑矩阵 。
由归纳假设, 等于从 到 的长度为 的旅行数。
那么从 到 的长度为 的旅行数,等于从 到某个与 相邻的顶点 的长度为 的旅行数,这正是 所表示的,因此归纳成立。因此,要计算长度为 且起点与终点相同的旅行数,只需计算 ,然后将其对角线上元素求和(即矩阵的迹)。
为了高效计算,我们可以使用二进制快速幂技术。设
$$I = \begin{bmatrix} 1 & 0 & \cdots & 0 \\ 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 1 \end{bmatrix} $$为单位矩阵,则:
$$A^k = \begin{cases} I, & \text{若 } k = 0, \\ \left(A^{k/2}\right)^2, & \text{若 } k > 0 \text{ 且 } k \text{ 为偶数}, \\ \left(A^{(k-1)/2}\right)^2 \cdot A, & \text{若 } k > 0 \text{ 且 } k \text{ 为奇数}. \end{cases} $$由于每一步将指数减半,该过程需要 步。
每一步进行 1 或 2 次 矩阵乘法,朴素算法为 。
因此总时间复杂度为 。
完整问题
现在回到原问题:计算长度为 、起点与终点相同且为特殊旅行的数量。
特殊旅行要求不连续两次使用同一条道路(即 )。
我们无法直接用一个简单矩阵的幂表示它,但可以尝试用邻接矩阵描述。设 为一个 矩阵,其 元素等于从 出发、到 结束的长度为 的特殊旅行的数量。
另外设 为度数矩阵(对角矩阵),其中 等于顶点 在图 中的度数。引理 2
以下等式成立:
- 对 ,有
证明
-
:长度为 1 的特殊旅行就是图中的边,显然成立。
-
: 对应所有长度为 2 的旅行(允许连续用同一条边返回)。
但特殊旅行不允许连续两次使用同一条边。长度为 2 的旅行中,连续用同一条边的情况正好是:从一个顶点 出发,走一条邻边,再原路返回。
这种旅行的数量正好是 ,即 的度数。因此去掉这些情况,得到 。 -
:
考虑 ,它表示长度为 的旅行,其中前 步是特殊旅行,最后一步任意走邻边(可能连续使用上一步的边)。
这正是我们想要的结果加上那些最后一步与倒数第二步使用了同一条边的非法情况。
非法情况可以这样描述:先走一个长度为 的特殊旅行到达某个顶点 ,然后走一条与 相邻的边(但不能是刚刚到达 的那条边,否则会在第 步到 步之间产生重复边吗?注意:这里“最后两步”指第 步和第 步),实际上需要更仔细分析。更准确的推导:
计数了所有长度为 的路径,其中前 步是特殊路径,第 步任意走一条邻边。
需要去除的情况是:第 步走的路与第 步走的路是同一条。
这等价于:先走一个长度为 的特殊路径到达某个顶点 ,然后从 走到某个邻点 (这条边记为 ),并且最后一步从 走回 沿同一条边 。
注意:从 走到 的这一步(第 步)不能是前一步(第 步)刚刚走过的边,但这是已经由 保证了(因为前 步已经是特殊路径)。
因此,对于每个长度为 的特殊路径终点 ,它可以走任意一条邻边 到 (共 种选择),但其中有一条边可能是第 步刚走过的吗?不是——因为第 步是进入 的最后一条边,这条边不能与第 步的边相同,否则第 步到第 步会重复边。
所以实际上,从 出发可选的边是 条(排除刚刚进入 的那条边)。这正是 对角元的意义。
因此,非法情况的计数是 。
于是:证毕。
高效计算
现在我们有一个线性递推关系,可以用矩阵快速幂求解。
构造一个 的分块矩阵:
$$L = \begin{bmatrix} A & I \\ -(D - I) & 0 \end{bmatrix} $$注意 是 的矩阵。
$$L \begin{bmatrix} X \\ Y \end{bmatrix} = \begin{bmatrix} A X + I Y \\ -(D - I) X + 0 \cdot Y \end{bmatrix} = \begin{bmatrix} A X + Y \\ -(D - I) X \end{bmatrix} $$
考虑 乘以一个列向量:但我们更常用如下形式(题解原文略有不同,我们用标准形式):
实际上原题解中给出的是:
$$L = \begin{bmatrix} A & -(D - I) \\ I & 0 \end{bmatrix} $$这样:
$$L \begin{bmatrix} S(k) \\ S(k-1) \end{bmatrix} = \begin{bmatrix} A S(k) - (D - I) S(k-1) \\ S(k) \end{bmatrix} = \begin{bmatrix} S(k+1) \\ S(k) \end{bmatrix} $$检查:
由递推 ,正是上式第一个块。
第二个块为 ,符合要求。因此:
$$\begin{bmatrix} S(k) \\ S(k-1) \end{bmatrix} = L^{k-2} \begin{bmatrix} S(2) \\ S(1) \end{bmatrix}, \quad \text{对于 } k \ge 2 $$其中 ,。
算法步骤
- 读入 ,建图,计算邻接矩阵 和度数矩阵 。
- 若 ,答案为 (因为无自环,对角线为 0)。
- 若 ,答案为 $\operatorname{tr}(A^2 - D) = \sum_i \left( (A^2)_{ii} - D_{ii} \right)$。
- 若 :
- 构造 矩阵 $L = \begin{bmatrix} A & -(D-I) \\ I & 0 \end{bmatrix}$。
- 计算 (用矩阵快速幂,复杂度 )。
- 计算初始向量 $V = \begin{bmatrix} \operatorname{vec}(S(2)) \\ \operatorname{vec}(S(1)) \end{bmatrix}$(这里 表示将 矩阵按行或列拉直为 维向量?注意:实际上 是 操作在矩阵块上,不是拉直。我们保持 为 矩阵,直接进行分块矩阵乘法。)
- 得到 。
- 答案为 ,即 对角线元素之和。
- 所有运算模 。
复杂度
- 时间:
- 空间:
总结
本题核心是将“禁止立即走回头路”的约束转化为线性递推,并用 分块矩阵快速幂求解。
这结合了图论、矩阵快速幂和递推关系求解,是 的经典解法。
- 1
信息
- ID
- 6424
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7.5
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者