Z 函数 
一些定义 
字符串下标以 0 0 0 Z ( i ) Z(i) Z ( i ) s s s s [ i ⋯   ] s[i\cdots] s [ i ⋯ ] s s s i i i 最长公共前缀长度 z ( 0 ) = 0 z(0) = 0 z ( 0 ) = 0 s [ 0 ⋯ z ( i ) − 1 ] s[0\cdots z(i)-1] s [ 0 ⋯ z ( i ) − 1 ] s [ i ⋯ i + z ( i ) − 1 ] s[i\cdots i+z(i)-1] s [ i ⋯ i + z ( i ) − 1 ] s s s i i i s s s s [ i ⋯ i + z ( i ) − 1 ] s[i\cdots i + z(i) - 1] s [ i ⋯ i + z ( i ) − 1 ] 
朴素算法 
朴素算法根据定义暴力来求即可暴力扩展的代码是 
1 while  (i + z[i] < n && s[z[i]] == s[i+z[i]]) z[i] += 1;
线性算法 
思想,在计算 z ( i ) z(i) z ( i ) z ( 0 ) , z ( 1 ) , ⋯ z ( i − 1 ) z(0), z(1), \cdots z(i-1) z ( 0 ) , z ( 1 ) , ⋯ z ( i − 1 ) 
对于 i i i [ i , i + z ( i ) − 1 ] [i, i+z(i)-1] [ i , i + z ( i ) − 1 ] i i i 匹配段 维护右端点最靠右 的匹配段,不妨记这样的匹配段是 [ l , r ] [l, r] [ l , r ] 
根据定义,我们有s [ l ⋯ r ] = s [ 0 ⋯ r − l ] s[l\cdots r] = s[0\cdots r-l] s [ l ⋯ r ] = s [ 0 ⋯ r − l ] s [ l ⋯ r ] s[l\cdots r] s [ l ⋯ r ] s s s 
对于当前匹配段 [ i , i + z ( i ) − 1 ] [i, i+z(i)-1] [ i , i + z ( i ) − 1 ] 
如果 i ⩽ r i \leqslant r i ⩽ r s [ i , r ] = s [ i − l , r − l ] s[i, r] = s[i-l, r-l] s [ i , r ] = s [ i − l , r − l ] z ( i − l ) z(i-l) z ( i − l ) z ( i ) ⩾ min  ( z ( i − l ) , r − i + 1 ) z(i) \geqslant \min \left(z(i-l), r-i+1 \right) z ( i ) ⩾ min ( z ( i − l ) , r − i + 1 ) 
如果 z ( i − l ) < r − i + 1 z(i-l) < r-i+1 z ( i − l ) < r − i + 1 z ( i ) = z ( i − l ) z(i) = z(i-l) z ( i ) = z ( i − l )  
否则的话,z ( i − l ) ⩾ r − i + 1 z(i-l) \geqslant r-i+1 z ( i − l ) ⩾ r − i + 1 z ( i ) = r − i + 1 z(i) = r-i+1 z ( i ) = r − i + 1 暴力扩展  z ( i ) z(i) z ( i )  
 
 
如果 i > r i > r i > r s [ i ] s[i] s [ i ] z ( i ) z(i) z ( i ) 
 
求出 z ( i ) z(i) z ( i ) s [ i , i + z ( i ) − 1 ] s[i, i+z(i)-1] s [ i , i + z ( i ) − 1 ] i + z ( i ) − 1 > r i+z(i)-1 > r i + z ( i ) − 1 > r l = i , r = i + z ( i ) − 1 l = i, r = i+z(i)-1 l = i , r = i + z ( i ) − 1 
 
 
应用 
匹配所有子串 t t t p p p t t t p p p 
构造一个新的字符串 s = p + # + t s = p + \# + t s = p + # + t # \# # s , t s, t s , t  
计算 s s s z z z t t t i ∈ [ 0 , ∣ t ∣ − 1 ] i \in [0, |t|-1] i ∈ [ 0 , ∣ t ∣ − 1 ] s s s lcp = z [ ∣ p ∣ + 1 + i ] \text{lcp} = z[|p|+1+i] lcp = z [ ∣ p ∣ + 1 + i ] lcp = ∣ p ∣ \text{lcp} = |p| lcp = ∣ p ∣ p p p t t t i i i  
 
本质不同子串数 n n n s s s s s s 
算法分析s s s s s s c c c 
首先,令 t = ( s + c ) − 1 t = (s+c)^{-1} t = ( s + c ) − 1 s + c s+c s + c c c c t t t c c c 
很显然,这样的前缀有 ∣ t ∣ |t| ∣ t ∣ { 1 , 2 , ⋯   , ∣ t ∣ } \{1, 2, \cdots, |t|\} { 1 , 2 , ⋯ , ∣ t ∣ } t t t 
计算 t t t z z z z max  z_{\max} z m a x  z max  z_{\max} z m a x  [ p , p + z max  − 1 ] [p, p+z_{\max}-1] [ p , p + z m a x  − 1 ] 子前缀 ,即长度 ⩽ z max  \leqslant z_{\max} ⩽ z m a x  
所以有 z max  z_{\max} z m a x  ∣ t ∣ − z max  |t| - z_{\max} ∣ t ∣ − z m a x  
字符串的整周期 n n n s s s t t t s s s t t t 
计算 s s s z z z n n n i i i i + z ( i ) = n i+z(i) = n i + z ( i ) = n  
 
前缀函数 
先看一些定义真前缀 是指 s s s 真后缀 指 s s s 
前缀函数 是一个长度为 n n n π \pi π π ( i ) \pi(i) π ( i ) 
如果子串 s [ 0 ⋯ i ] s[0\cdots i] s [ 0 ⋯ i ] S [ 0 , k − 1 ] S[0, k-1] S [ 0 , k − 1 ] s [ i − k + 1 , i ] s[i-k+1, i] s [ i − k + 1 , i ] π ( i ) \pi(i) π ( i ) π ( i ) = k \pi(i) = k π ( i ) = k  
如果有不止一对相等的,那么 π ( i ) \pi(i) π ( i )  
如果没有相等的,那么 π ( i ) = 0 \pi(i) = 0 π ( i ) = 0  
 
π ( i ) \pi(i) π ( i ) s [ 0 ⋯ i ] s[0\cdots i] s [ 0 ⋯ i ] π ( 0 ) = 0 \pi(0) = 0 π ( 0 ) = 0 
计算前缀函数的朴素算法 
一开始令 π ( 0 ) = 0 \pi(0) = 0 π ( 0 ) = 0 i ∈ [ 1 → n − 1 ] i \in [1\to n-1] i ∈ [ 1 → n − 1 ]  
然后尝试真前缀长度 j j j j = i j = i j = i j j j π ( i ) = j \pi(i) = j π ( i ) = j j ← j − 1 j \leftarrow j-1 j ← j − 1 j = 0 j = 0 j = 0  
如果 j = 0 j = 0 j = 0 π ( i ) = 0 \pi(i) = 0 π ( i ) = 0 i i i  
 
高效算法 
第一个优化 相邻的前缀函数值最多增加  1 1 1 i i i s [ 0 ⋯ π ( i ) − 1 ] s[0\cdots \pi(i) - 1] s [ 0 ⋯ π ( i ) − 1 ] i ← i + 1 i \leftarrow i+1 i ← i + 1 最好的情况 就是 s [ π ( i ) ] = s [ i + 1 ] s[\pi(i)] = s[i+1] s [ π ( i ) ] = s [ i + 1 ] π ( i + 1 ) = π ( i ) + 1 \pi(i+1) = \pi(i) + 1 π ( i + 1 ) = π ( i ) + 1 
所以 i ← i + 1 i \leftarrow i+1 i ← i + 1 1 1 1 i i i j ∈ [ π ( i − 1 ) + 1 → 0 ] j \in [\pi(i-1) + 1 \to 0] j ∈ [ π ( i − 1 ) + 1 → 0 ] 
1 2 3 4 5 for  (int i = 1; i < n; i++) {    for  (int j = pi[i-1] + 1; j >= 0; j--) {         // ...     } } 
这个算法的复杂度取决于最大字符串比较次数 ,j = π ( i − 1 ) + 1 j = \pi(i-1) + 1 j = π ( i − 1 ) + 1 π ( i ) \pi(i) π ( i ) 最好的情况 下才会增长,什么是最好的情况?s [ π ( i ) ] = s [ i + 1 ] s[\pi(i)] = s[i+1] s [ π ( i ) ] = s [ i + 1 ] j ∈ [ π ( i − 1 ) + 1 → 0 ] j \in [\pi(i-1)+1 \to 0] j ∈ [ π ( i − 1 ) + 1 → 0 ] 1 1 1 
而如果比较次数超过 1 1 1 π ( i ) \pi(i) π ( i ) O ( n ) O(n) O ( n ) O ( n 2 ) O(n^2) O ( n 2 ) 
第二个优化 s [ 0 ⋯ π ( i ) − 1 ] + s [ π ( i ) ] s[0\cdots \pi(i)-1] + s[\pi(i)] s [ 0 ⋯ π ( i ) − 1 ] + s [ π ( i ) ] s [ 0 ⋯ i ] + s [ i + 1 ] s[0\cdots i] + s[i+1] s [ 0 ⋯ i ] + s [ i + 1 ] s [ π ( i ) ] = s [ i + 1 ] s[\pi(i)] = s[i+1] s [ π ( i ) ] = s [ i + 1 ] s [ i + 1 ] ≠ s [ π ( i ) ] s[i+1] \neq s[\pi(i)] s [ i + 1 ]  = s [ π ( i ) ] 
从递推的角度来考虑 s [ 0 ⋯ i ] s[0\cdots i] s [ 0 ⋯ i ] π ( i ) \pi(i) π ( i ) j j j s [ 0 ⋯ j − 1 ] = s [ i − j + 1 ⋯ i ] s[0\cdots j-1] = s[i-j+1\cdots i] s [ 0 ⋯ j − 1 ] = s [ i − j + 1 ⋯ i ] s [ j ] = s [ i + 1 ] s[j] = s[i+1] s [ j ] = s [ i + 1 ] π ( i + 1 ) = j \pi(i+1) = j π ( i + 1 ) = j s [ j ] ≠ s [ i + 1 ] s[j] \neq s[i+1] s [ j ]  = s [ i + 1 ] j j j j ( 2 ) j^{(2)} j ( 2 ) j = 0 j = 0 j = 0 s [ i + 1 ] ≠ s [ 0 ] s[i+1] \neq s[0] s [ i + 1 ]  = s [ 0 ] π ( i + 1 ) = 0 \pi(i+1) = 0 π ( i + 1 ) = 0 
下面考虑  j j j 如何求 s [ π ( i ) ] ≠ s ( i + 1 ) s[\pi(i)] \neq s(i+1) s [ π ( i ) ]  = s ( i + 1 ) s [ 0 ⋯ π ( i ) − 1 ] = s [ i − π ( i ) + 1 ⋯ i ] s[0\cdots \pi(i)-1] = s[i-\pi(i)+1\cdots i] s [ 0 ⋯ π ( i ) − 1 ] = s [ i − π ( i ) + 1 ⋯ i ] j j j s [ 0 ⋯ j − 1 ] = s [ i − j + 1 ⋯ i ] s[0\cdots j-1] = s[i-j+1\cdots i] s [ 0 ⋯ j − 1 ] = s [ i − j + 1 ⋯ i ] [ i − j + 1 , i ] [i-j+1, i] [ i − j + 1 , i ] [ 0 , π ( i ) − 1 ] [0, \pi(i)-1] [ 0 , π ( i ) − 1 ] 后一半长度为 j j j  s [ 0 ⋯ j − 1 ] = s [ i − j + 1 ⋯ i ] = s [ π ( i ) − j ⋯ π ( i ) − 1 ] s[0 \cdots j-1] = s[i-j+1\cdots i] = s[\pi(i) - j \cdots \pi(i) - 1] s [ 0 ⋯ j − 1 ] = s [ i − j + 1 ⋯ i ] = s [ π ( i ) − j ⋯ π ( i ) − 1 ] 
换句话说,j j j s [ ⋯ π ( i ) − 1 ] s[\cdots \pi(i) - 1] s [ ⋯ π ( i ) − 1 ] j = π ( π ( i ) − 1 ) j = \pi\left(\pi(i) - 1 \right) j = π ( π ( i ) − 1 ) j ( 2 ) = π ( j − 1 ) j^{(2)} = \pi(j-1) j ( 2 ) = π ( j − 1 ) 
j j j 状态转移方程如下 j ( n ) = π ( j ( n − 1 ) − 1 ) ,   ( j ( n − 1 ) > 0 ) \displaystyle j^{(n)} = \pi\left(j^{(n-1)} - 1 \right), \ (j^{(n-1)} > 0) j ( n ) = π ( j ( n − 1 ) − 1 ) ,   ( j ( n − 1 ) > 0 ) 
应用 
kmp算法 
给定一个文本串 t t t s s s t t t s s s 
构造一个字符串 s + # + t s + \# + t s + # + t # \# # s s s t t t n n n s s s m m m t t t 0 0 0 
我们考虑 i ∈ [ n + 1 → n + m ] i \in [n+1 \to n+m] i ∈ [ n + 1 → n + m ] π ( i ) = n \pi(i) = n π ( i ) = n t t t s s s r = i − ( n + 1 ) r = i-(n+1) r = i − ( n + 1 ) n n n l = i − ( n + 1 ) − n + 1 = i − 2 n l = i - (n+1) - n + 1 = i - 2n l = i − ( n + 1 ) − n + 1 = i − 2 n 
字符串的周期 
对字符串 s s s 0 < p ⩽ ∣ s ∣ 0 < p \leqslant |s| 0 < p ⩽ ∣ s ∣ s [ i ] = s [ i + p ] s[i] = s[i+p] s [ i ] = s [ i + p ] 所有  i ∈ [ 0 , ∣ s ∣ − p − 1 ] i \in [0, |s|-p-1] i ∈ [ 0 , ∣ s ∣ − p − 1 ] p p p s s s 
对字符串 s s s 0 ⩽ r < ∣ s ∣ 0 \leqslant r < |s| 0 ⩽ r < ∣ s ∣ s s s r r r r r r s s s r r r s s s 
那么可以推出s s s r r r ∣ s ∣ − r |s| - r ∣ s ∣ − r s s s 
注意,如果 ∣ s ∣ |s| ∣ s ∣ i ∈ [ 0 , ∣ s ∣ − p − 1 ] i \in [0, |s|-p-1] i ∈ [ 0 , ∣ s ∣ − p − 1 ] [ 0 , r − 1 ] [0, r-1] [ 0 , r − 1 ] s [ i ] = s [ i + p ] s[i] = s[i+p] s [ i ] = s [ i + p ] 
 
根据前缀函数的定义,可以得到 s s s π ( n − 1 ) , π ( π ( n − 1 ) − 1 ) , ⋯ \displaystyle \pi(n-1), \pi \left(\pi(n-1) - 1 \right), \cdots π ( n − 1 ) , π ( π ( n − 1 ) − 1 ) , ⋯ 
那么 s s s π ( n − 1 ) \pi(n-1) π ( n − 1 ) s s s n − π ( n − 1 ) n - \pi(n-1) n − π ( n − 1 ) 
统计每个前缀出现次数 
第一个问题 n n n s s s s [ 0 ⋯ i ] s[0\cdots i] s [ 0 ⋯ i ] 
考虑位置 i i i π ( i ) \pi(i) π ( i ) π ( i ) \pi(i) π ( i ) i i i i i i i i i 
那么这个问题就转换成为j j j i i i j ( 2 ) < j j^{(2)} < j j ( 2 ) < j i i i 
因此,以 i i i 长度从大到小 依次是π ( i ) , π ( π ( i ) − 1 ) , π ( π ( π ( i ) − 1 ) − 1 ) , ⋯ \displaystyle \pi(i), \pi \left(\pi(i) - 1 \right), \pi \left(\pi\left(\pi(i)-1 \right) - 1 \right), \cdots π ( i ) , π ( π ( i ) − 1 ) , π ( π ( π ( i ) − 1 ) − 1 ) , ⋯ 
假设我们已经知道了 x = π ( i ) x = \pi(i) x = π ( i ) a n s ( x ) ans(x) a n s ( x ) { π ( x − 1 ) ⋯   } \{\pi(x-1)\cdots \} { π ( x − 1 ) ⋯ } x x x x x x { π ( x − 1 ) , π ( p i ( x − 1 ) − 1 ) , ⋯   } \{\pi(x-1), \pi(pi(x-1) - 1), \cdots \} { π ( x − 1 ) , π ( p i ( x − 1 ) − 1 ) , ⋯ } 
由此从后往前扫描每一个可能的 π = x \pi = x π = x a n s ( π ( x − 1 ) ) + = a n s ( x ) ans(\pi(x-1)) += ans(x) a n s ( π ( x − 1 ) ) + = a n s ( x ) 
1 2 3 4 vector<int> ans(n+1, 0); for  (int i = 0; i < n; i++) ans[ pi[i] ] += 1;for  (int x = n-1; x > 0; x--) ans[ pi[x-1] ] += ans[x];for  (int i = 0; i <= n; i++) ans[i]++;
第二个问题 s [ 0 ⋯ i ] s[0\cdots i] s [ 0 ⋯ i ] t t t 
构造一个字符串 s + # + t s + \# + t s + # + t i ⩾ n + 1 i \geqslant n+1 i ⩾ n + 1 π ( i ) \pi(i) π ( i ) 
一个字符串中本质不同的子串数目 
一个长度为 n n n s s s s s s 
假设我们已经知道了当前 s s s r e s res r e s s s s c c c c c c 没有遇到过 的子串,对这些子串计数
构造字符串 t = s + c t = s+c t = s + c t − 1 t^{-1} t − 1 t − 1 t^{-1} t − 1 t − 1 t^{-1} t − 1 
我们计算 t − 1 t^{-1} t − 1 π max  \pi_{\max} π m a x  t − 1 t^{-1} t − 1 π max  \pi_{\max} π m a x  
因此新添加一个字符后,新出现的子串数目为∣ s ∣ + 1 − π max  \displaystyle |s| + 1 - \pi_{\max} ∣ s ∣ + 1 − π m a x  
字符串压缩 
给定一个长度为 n n n s s s s s s t t t s s s t t t 
显然我们只需要知道 t t t t t t s s s ∣ t ∣ |t| ∣ t ∣ 
计算 s s s π ( n − 1 ) \pi(n-1) π ( n − 1 ) k = n − π ( n − 1 ) k = n - \pi(n-1) k = n − π ( n − 1 ) 证明 k ∣ n k \mid n k ∣ n k k k n n n 
先证必要性k ∣ n k \mid n k ∣ n k k k n − k = π ( n − 1 ) n - k = \pi(n-1) n − k = π ( n − 1 ) n − k n - k n − k n − k n-k n − k 
s 0 s 1 s 2 ⏟ k s 3 ⋯ ⋯ s π ( n − 1 ) − 1 ⏞ n − k = π ( n − 1 ) s n − 3 s n − 2 s n − 1 ⏞ k \displaystyle \overbrace{ \underbrace{ s_0s_1s_2 }_{k}s_3\cdots\cdots s_{\pi(n-1)-1} }^{n-k= \pi(n-1)}\overbrace{ s_{n-3}s_{n-2}s_{n-1} } ^{k} k s 0  s 1  s 2    s 3  ⋯ ⋯ s π ( n − 1 ) − 1   n − k = π ( n − 1 )  s n − 3  s n − 2  s n − 1   k  
从图中可以发现,长度为 k k k [ 0 , π ( n − 1 ) − 1 ] [0, \pi(n-1)-1] [ 0 , π ( n − 1 ) − 1 ] k k k s s s k k k 
再证明这个解是最优的k k k π ( n − 1 ) > n − k \pi(n-1) > n-k π ( n − 1 ) > n − k k = n − π ( n − 1 ) k = n - \pi(n - 1) k = n − π ( n − 1 ) 
如果 k ∤ n k \nmid n k ∤ n n n n 
Educational Codeforces Round 118 
D. MEX Sequences 题目大意 < x 1 , x 2 , ⋯   , x k > \left<x_1, x_2, \cdots, x_k \right> ⟨ x 1  , x 2  , ⋯ , x k  ⟩ mex-correct \text{mex-correct} mex-correct 1 ⩽ i ⩽ k 1 \leqslant i \leqslant k 1 ⩽ i ⩽ k ∣ x i − mex ( x 1 , x 2 , ⋯   , x i ) ∣ ⩽ 1 |x_i - \text{mex}(x_1, x_2, \cdots, x_i)| \leqslant 1 ∣ x i  − mex ( x 1  , x 2  , ⋯ , x i  ) ∣ ⩽ 1 n n n a a a mex-correct \text{mex-correct} mex-correct 998244353 998244353 9 9 8 2 4 4 3 5 3 a i 1 a i 2 ⋯ a i m a_{i1}a_{i2}\cdots a_{im} a i 1  a i 2  ⋯ a i m  
算法分析 mex \text{mex} mex 
如果一个序列的前缀 mex = x \text{mex} = x mex = x [ 0 , 1 , ⋯ x ] [0, 1, \cdots x] [ 0 , 1 , ⋯ x ] 单调不降 的< x < x < x > x > x > x 来回横跳 d p dp d p 
 
现在我们考虑第 i i i mex [ 0 ⋯ i ] = x \text{mex}[0\cdots i] = x mex [ 0 ⋯ i ] = x [ 0 , i ] : < 0 , ⋯   , 0 ‾ , 1 , ⋯   , 1 ‾ , ⋯   , x − 1 , ⋯   , x − 1 ‾ > [0, i] :\left<\underline{0,\cdots, 0}, \underline{1, \cdots, 1}, \cdots, \underline{x-1,\cdots, x-1} \right> [ 0 , i ] : ⟨ 0 , ⋯ , 0  , 1 , ⋯ , 1  , ⋯ , x − 1 , ⋯ , x − 1  ⟩ [ 0 , i ] : < 0 , ⋯   , 0 ‾ , 1 , ⋯   , 1 ‾ , ⋯   , x − 1 , ⋯   , x − 1 ‾ , x + 1 , ⋯   , x + 1 ‾ > [0, i]: \left<\underline{0, \cdots, 0}, \underline{1, \cdots, 1}, \cdots, \underline{x-1, \cdots, x-1}, \underline{x+1, \cdots, x+1} \right> [ 0 , i ] : ⟨ 0 , ⋯ , 0  , 1 , ⋯ , 1  , ⋯ , x − 1 , ⋯ , x − 1  , x + 1 , ⋯ , x + 1  ⟩ 
d p i ( x ) dp_i(x) d p i  ( x ) i i i mex [ 0 ⋯ i ] = x \text{mex}[0\cdots i] = x mex [ 0 ⋯ i ] = x d p dp d p d p i ( x ) dp_{i}(x) d p i  ( x ) d p i + 1 ( x + 1 ) dp_{i+1}(x+1) d p i + 1  ( x + 1 ) a i = x a_i = x a i  = x d p i ( x ) dp_{i}(x) d p i  ( x ) d p i + 1 ( x + 2 ) dp_{i+1}(x+2) d p i + 1  ( x + 2 ) ∣ mex − x ∣ = 2 |\text{mex} -x| = 2 ∣ mex − x ∣ = 2 
 
情形1 单调不降 d p 1 ( i , x ) dp1(i, x) d p 1 ( i , x ) i i i 考虑 的意思是,将要把 a [ i ] a[i] a [ i ] mex \text{mex} mex x x x 
a [ i ] < x − 1   or   a [ i ] > x + 1 a[i] < x-1 \ \textbf{or} \ a[i] > x+1 a [ i ] < x − 1   or   a [ i ] > x + 1 a [ i ] a[i] a [ i ] ∣ mex − a [ i ] ∣ ⩾ 2 |\text{mex} - a[i]| \geqslant 2 ∣ mex − a [ i ] ∣ ⩾ 2 a [ i ] = x − 1 a[i] = x-1 a [ i ] = x − 1 a [ i ] a[i] a [ i ] mex \text{mex} mex d p 1 ( i + 1 , x ) ← d p 1 ( i , x ) dp1(i+1, x) \leftarrow dp1(i, x) d p 1 ( i + 1 , x ) ← d p 1 ( i , x ) a [ i ] = x a[i] = x a [ i ] = x a [ i ] a[i] a [ i ] mex = x + 1 \text{mex} = x+1 mex = x + 1 d p 1 ( i + 1 , x + 1 ) ← d p 1 ( i , x ) dp1(i+1, x+1) \leftarrow dp1(i, x) d p 1 ( i + 1 , x + 1 ) ← d p 1 ( i , x ) a [ i ] = x + 1 a[i] = x+1 a [ i ] = x + 1 a [ i ] a[i] a [ i ] mex \text{mex} mex x x x 第二种情形 了d p 2 ( i + 1 , x ) = d p 1 ( i , x ) dp2(i+1, x) = dp1(i, x) d p 2 ( i + 1 , x ) = d p 1 ( i , x )  
情形2 来回横跳 d p 2 ( i , x ) dp2(i, x) d p 2 ( i , x ) 
a [ i ] < x − 1   or   a [ i ] > x + 1 a[i] < x-1 \ \textbf{or} \ a[i] > x+1 a [ i ] < x − 1   or   a [ i ] > x + 1 a [ i ] a[i] a [ i ] a [ i ] = x − 1 a[i] = x-1 a [ i ] = x − 1 a [ i ] a[i] a [ i ] mex \text{mex} mex d p 2 ( i + 1 , x ) ← d p 2 ( i , x ) dp2(i+1, x) \leftarrow dp2(i, x) d p 2 ( i + 1 , x ) ← d p 2 ( i , x ) a [ i ] = x a[i] = x a [ i ] = x a [ i ] a[i] a [ i ] mex = x + 2 \text{mex} = x+2 mex = x + 2 x + 1 x+1 x + 1 ∣ mex − a [ i ] ∣ = ∣ x + 2 − x ∣ = 2 |\text{mex} - a[i]| = |x+2 - x| = 2 ∣ mex − a [ i ] ∣ = ∣ x + 2 − x ∣ = 2 a [ i ] = x + 1 a[i] = x+1 a [ i ] = x + 1 a [ i ] a[i] a [ i ] mex \text{mex} mex d p 2 ( i + 1 , x ) ← d p 2 ( i , x ) dp2(i+1, x) \leftarrow dp2(i, x) d p 2 ( i + 1 , x ) ← d p 2 ( i , x )  
综上所述 x = a [ i ] x = a[i] x = a [ i ] 1 1 1 d p 1 i + 1 ( x + 1 ) + = d p 1 i ( x + 1 ) , d p 1 i + 1 ( x + 1 ) + = d p 1 i ( x ) , d p 2 i + 1 ( x − 1 ) + = d p 1 i ( x − 1 ) dp1_{i+1}(x+1) += dp1_{i}(x+1), \quad dp1_{i+1}(x+1) += dp1_{i}(x), \quad dp2_{i+1}(x-1) += dp1_{i}(x-1) d p 1 i + 1  ( x + 1 ) + = d p 1 i  ( x + 1 ) , d p 1 i + 1  ( x + 1 ) + = d p 1 i  ( x ) , d p 2 i + 1  ( x − 1 ) + = d p 1 i  ( x − 1 ) 
对于情形 2 2 2 d p 2 i + 1 ( x + 1 ) + = d p 2 i ( x + 1 ) , d p 2 i + 1 ( x − 1 ) + = d p 2 i ( x − 1 ) dp2_{i+1}(x+1) += dp2_{i}(x+1), \quad dp2_{i+1}(x-1) += dp2_{i}(x-1) d p 2 i + 1  ( x + 1 ) + = d p 2 i  ( x + 1 ) , d p 2 i + 1  ( x − 1 ) + = d p 2 i  ( x − 1 ) 
在实现的时候,可以省略第一维,但是要注意 d p dp d p d p 2 i + 1 ( x − 1 ) + = d p 1 i ( x − 1 ) dp2_{i+1}(x-1) += dp1_i(x-1) d p 2 i + 1  ( x − 1 ) + = d p 1 i  ( x − 1 ) d p 2 i + 1 ( x − 1 ) + = d p 2 i ( x − 1 ) dp2_{i+1}(x-1) += dp2_i(x-1) d p 2 i + 1  ( x − 1 ) + = d p 2 i  ( x − 1 ) d p 2 ( x − 1 ) + = d p 1 ( x − 1 ) dp2(x-1) += dp1(x-1) d p 2 ( x − 1 ) + = d p 1 ( x − 1 ) d p 2 i + 1 ( x − 1 ) dp2_{i+1}(x-1) d p 2 i + 1  ( x − 1 ) d p 2 i ( x − 1 ) dp2_{i}(x-1) d p 2 i  ( x − 1 ) d p 2 i + 1 ( x − 1 ) dp2_{i+1}(x-1) d p 2 i + 1  ( x − 1 ) d p 2 ( x − 1 ) dp2(x-1) d p 2 ( x − 1 ) d p 2 i + 1 ( x − 1 ) dp2_{i+1}(x-1) d p 2 i + 1  ( x − 1 )