1 条题解
-
0
核心思路
1. 状态设计
由于边权只有 ,我们可以将每个节点拆成 3 个状态:
- : 到达 且最后一步走的是长度为 的边
- : 到达 且最后一步走的是长度为 的边
- : 到达 且最后一步走的是长度为 的边
实际上代码中用的是:
- : 表示还需要走 1 步才能完成一条完整路径
- : 表示还需要走 2 步才能完成一条完整路径
- : 表示还需要走 3 步才能完成一条完整路径
2. 转移矩阵构建
状态转移规则:
- 从 到 : 需要边权 的边
- 从 到 : 需要边权 的边
- 从 到 : 需要边权 的边
内部转移(延迟计数):
3v-2 → 3v-1 → 3v这样就把长边拆成了多个长度为 1 的"步骤"。
3. 路径计数公式
设 表示长度为 的到达 的路径数。
转移:
$$f_L[v] = \sum_{u→v \text{ with weight } w} f_{L-w}[u] $$由于 ,这是三阶线性递推,可以用矩阵快速幂。
4. 累计路径数
我们要求的是长度 的路径总数是否 。
在矩阵中加入一个累计节点 :
- 从每个完整路径状态 连到 (计数一次)
- 自环保持累计和
这样矩阵的 就是长度 当前幂次的路径总数。
5. 二分答案
使用倍增(二进制拆分)来二分:
- 从高位到低位尝试
- 用矩阵快速幂检查路径数
- 如果 ,就加上这一位
6. 边界处理
- 初始状态:每个节点作为起点,
- 最终答案要减去 (去掉长度为 0 的路径)
- 用
__int128和min(..., L)防止溢出
时间复杂度
- 矩阵大小
- 矩阵乘法
- 二分 次
- 总复杂度 ,对于 可接受
这种状态拆分+矩阵快速幂+二分的方法巧妙处理了边权多样性和超大 的问题。
- 1
信息
- ID
- 3850
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者