日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【manacher】双倍回文(金牌导航 manacher-2/luogu 4287)

發布時間:2023/12/3 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。