0%

注意,防止哨兵值参与计算,如果是 INF 哨兵值,就直接 continue

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
\section{错误六:答案计算缺少 $+\infty$ 守卫}
%======================================================================

\subsection*{错误代码}
\begin{minted}{cpp}
ll lans = INF;
for (int num1 = 0; num1 < 2; ++num1) {
if (d[num1][1] == INF) continue;
ll val = d[num1][1] + 1;
lans = min(lans, val);
}
// 缺少:if (lans == INF) continue;
ans += lans % mod * dp[status] % mod;
ans %= mod;
\end{minted}

\subsection*{错误分析}
当某个自动机状态 $D$$d_{01}$$d_{11}$ 均为 $+\infty$ 时,意味着落在该状态的子序列无法完成合法划分,其 $f$ 值为 $0$,不应对答案有任何贡献。

但如果缺少 \texttt{if (lans == INF) continue;},\texttt{lans} 仍为初始值 \texttt{INF}($= 2^{61} - 1$),这个巨大的数值会被乘以 \texttt{dp[status]} 后加入答案,导致结果完全错误。

\subsection*{修复}
\begin{minted}{cpp}
if (lans == INF) continue; // f=0 的状态不贡献答案
\end{minted}

\subsection*{教训}
使用哨兵值(如 \texttt{INF})初始化 \texttt{min} 变量时,计算结束后必须检查结果是否仍为哨兵值。如果是,说明没有任何有效候选,必须跳过后续计算,否则哨兵值会作为"正常数值"参与运算。