试题描述
|
输入一个字符串S,输出S的最长连续回文子串长度。 |
输入
|
输入一个字符串S。
|
输出
|
输出S的最长连续回文子串长度
|
输入示例
|
abacbbc
|
输出示例
|
4
|
其他说明
|
1<=|S|<=1000000
|
这就是传说中的萌萌哒马拉车算法(manacher)啦
首先为了方便处奇偶两种情况,将S重新变成新的字符串T,如abacddc变成#a#b#a#c#d#d#c#
再次为了方便处理越界,将字符串首尾加一个奇怪的不匹配字符,如将abacddc变成~#a#b#a#c#d#d#c#`
请大家想一想这样的好处
考虑暴力算法,枚举回文串中心,暴力向两边匹配
rep(1,n-1) { int t=1; while(s[i-t]==s[i+t]) t++; ans=max(ans,t-1); }
这样是O(N^2),考虑优化
我们定义P[i]表示位置i的最长匹配长度,考虑利用之前的匹配信息。
这样就是p[i]=p[2*id-i]
这样就是p[i]=mx-i
写成代码就是这样
#include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=2000010; char s[maxn]; int p[maxn]; int solve(char* s2) { int n=1,id=0,mx=0,ans=0; for(int i=0;s2[i]!='