Manacher 學習筆記
阿新 • • 發佈:2022-03-29
if(2 * maxn - i >= 1)
f[i] = min(f[2 * maxn - i],maxr - i);
else
f[i] = maxr - i;
關於這個演算法,最難以理解的部分也就這裡,也就是判斷 \(i\) 的最長迴文長度的下界。
首先定義 \(j\) 為 \(i\) 關於 \(maxn\) 的對稱點,\(mxr\) 為已有迴文半徑覆蓋到的最右點,\(maxn\) 為其的中心點
首先關於 \(j\) 的尋找,因為 \(maxn = \frac{i-j}{2}\),所以可以化簡得:\(2\times maxn = i - j\),所以 \(j = 2\times maxn - i\)
關於第一行的判斷條件,也就是在判斷 \(j\) 的存在,然後看後面的兩種情況。
1:若 \(f[j] < maxr - i\),我們選擇的下界會是 \(f[j]\),則有下圖
其中用紅線代表 \(i,j\) 的迴文範圍,\(maxr- i\) 也就是 \(i\) 到 \(maxr\) 的距離。首先因為這一長段都是以 \(maxn\) 為中心的迴文子串,所以其實以 \(j\) 為中心的迴文子串也在以 \(i\) 為中心的迴文子串那裡(不一定完整),因為 \(j\) 的迴文半徑小於 \(i\) 到 \(maxr\) 的距離,所以以 \(j\) 為中心的整個迴文串都完整地到了 \(i\)
2:若 \(f[j] > maxr - i\),我們選擇的下界會是 \(maxr - i\),則有下圖:
此時也就相當於 \(j\) 的迴文半徑的長度超過了 \(maxn\) 的限制,也就是以 \(j\) 為中心的迴文串只有一部分因為 $maxn $ 的限制而來到了 \(i\) 的位置,而這一部分的長度也就是 $j $ 到 $maxn $ 限制的左端點的距離,也就是 \(maxr - i\)