【manacher】双倍回文(金牌导航 manacher-2/luogu 4287)
生活随笔
收集整理的這篇文章主要介紹了
【manacher】双倍回文(金牌导航 manacher-2/luogu 4287)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
雙倍回文
金牌導航 manacher-2
luogu 4287
題目大意
設串為x,將其取反為x’,定義雙倍回文為形如xx’xx’的串
現在給你一個字符串,讓你求最大雙倍回文子串
輸入樣例
16 ggabaabaabaaball輸出樣例
12數據范圍
N?105N\leqslant 10^5N?105
解題思路
對于該字符串,可以用manacher求回文子串,在求回文子串的同時判斷是否雙倍回文
對于通過對稱得到最小回文長度的,因為對稱,所以不用判斷
對于字符判斷使其回文長度增加的,每增加一次就判斷一次
這樣就可以得到最大雙倍回文子串長度了
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 1000050 using namespace std; int n, p, mx, ans, v[N]; char s[N]; string str; int main() {scanf("%d", &n);cin>>str;s[0] = '/';s[1] = '#';for (int i = 1; i <= n; ++i)s[i * 2] = str[i - 1], s[i * 2 + 1] = '#';s[n * 2 + 2] = '|';n = n * 2 + 1;p = 1;mx = 1;for (int i = 1; i <= n; ++i){if (i < mx) v[i] = min(v[p * 2 - i], mx - i);//對稱就不用判斷了else v[i] = 1;while(s[i - v[i]] == s[i + v[i]]){v[i]++;if (i&1 && v[i] % 4 == 0 && v[i - v[i] / 2] - 1 >= v[i] / 2)//判斷是否符合雙倍回文ans = max(ans, v[i]);//因為有‘#’乘除2就抵消了}if (i + v[i] > mx){mx = i + v[i];p = i;}}printf("%d", ans);return 0; }總結
以上是生活随笔為你收集整理的【manacher】双倍回文(金牌导航 manacher-2/luogu 4287)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【决策单调性】玩具装箱(金牌导航 决策单
- 下一篇: 电脑就永远替代不了电视电脑就永远替代不了