【洛谷】P4555 [國家集訓隊]最長雙迴文串
阿新 • • 發佈:2022-03-20
P4555 [國家集訓隊]最長雙迴文串
題源:https://www.luogu.com.cn/problem/P4555
原理:Manacher
還真比KMP好理解
解決最長迴文串問題
轉化為長度為奇數的迴文串
原串長度 = 新串長度半徑 - 1
1. 轉化:首位加不同字元,中間加 #
(圖片源自AcWing)
2. 求p[i]:以 \(s_i\) 為中心的最大回文串的半徑(含中心)
3. 最大半徑 - 1 即為所求
注意要用char陣列,因為string是動態擴容的,很有可能訪問到非法邊界
板子:
void init (){ int k = 0; b[k ++] = '$', b[k ++] = '#'; for (int i = 0; i < a.size(); i ++) b[k ++] = a[i], b[k ++] = '#'; b[k ++] = '^'; n = k; }//心裡要有張圖,構造的時候可不能錯 void manacher (){ init(); int mr = 0, mid; for (int i = 1; i < n; i ++){ if (i < mr) p[i] = min (mr - i, p[2 * mid - i]); else p[i] = 1;//超過邊界就不是迴文了 while (b[i + p[i]] == b[i - p[i]]) p[i] ++; if (i + p[i] > mr) mr = i + p[i], mid = i;//找到更大的串了,更新邊界 ans = max (ans, p[i] - 1); } }
思路
一會兒再肝~