Skip to content

Commit fc66f54

Browse files
authored
fix(string/pam.md): 修正了最小回文划分的优化中 g 数组相关公式的错误 (OI-wiki#4592)
fix(string/pam.md): 修正了最小回文划分的优化中 g 数组相关公式的错误。
1 parent 1f48dce commit fc66f54

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

docs/string/pam.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ $s$ 的所有回文后缀按照长度排序后,可以划分成 $\log |s|$ 段
182182

183183
根据上面证明的结论,如果使用 $slink$ 指针向上跳的话,每向后填加一个字符,只需要向上跳 $O(\log |s|)$ 次。因此,可以考虑将一个等差数列表示的所有回文串的 $dp$ 值之和(在原问题中指 $\min$),记录到最长的那一个回文串对应节点上。
184184

185-
$g[v]$ 表示 $v$ 所在等差数列的 $dp$ 值之和,且 $v$ 是这个等差数列中长度最长的节点,则 $g[v]=\sum_{x,slink[x]=v} dp[i-len[x]]$,这里 $i$ 是当前枚举到的下标。
185+
$g[v]$ 表示 $v$ 所在等差数列的 $dp$ 值之和,且 $v$ 是这个等差数列中长度最长的节点,则 $g[v]=\sum_{slink[x]=slink[v]} dp[i-len[x]]$,这里 $i$ 是当前枚举到的下标。
186186

187187
下面我们考虑如何更新 $g$ 数组和 $dp$ 数组。以下图为例,假设当前枚举到第 $i$ 个字符,回文树上对应节点为 $x$。$g[x]$ 为橙色三个位置的 $dp$ 值之和(最短的回文串 $slink[x]$ 算在下一个等差数列中)。$fail[x]$ 上一次出现位置是 $i-diff[x]$(在 $i-diff[x]$ 处结束),$g[fail[x]]$ 包含的 $dp$ 值是蓝色位置。因此,$g[x]$ 实际上等于 $g[fail[x]]$ 和多出来一个位置的 $dp$ 值之和,多出来的位置是 $i-(len[slink[x]]+diff[x])$。最后再用 $g[x]$ 去更新 $dp[i]$,这部分等差数列的贡献就计算完毕了,不断跳 $slink[x]$,重复这个过程即可。具体实现方式可参考例题代码。
188188

0 commit comments

Comments
 (0)