Acwing139. 回文子串的最大长度(Manacher算法)
如果一个字符串正着读和倒着读是一样的,则称它是回文的。 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少。
输入格式
输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个小写字符的形式给出。 输入以一个以字符串“END”(不包括引号)开头的行表示输入终止。
输出格式
对于输入中的每个测试用例,输出测试用例编号和最大回文子串的长度(参考样例格式)。 每个输出占一行。
输入样例:
abcbabcbabcba
abacacbaaaab
END
输出样例:
Case 1: 13
Case 2: 6
Manacher (马拉车)算法的简单应用
挺有意思的一种计算最长回文串的算法,实现起来也较为简便,时间复杂度 O(n) ```
#include<bits/stdc++.h> #define IL inline #define ll long long #define R register int using namespace std; const int N=2e6+5;//数组记得两倍大 int p[N]; char s[N],f[N]; IL int read() { int f=1;char ch; while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1; int res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return f*res; } int init(){ int n=strlen(s+1); f[1]='@';f[2]='#'; int j=2; for(R i=1;i<=n;++i){ f[++j]=s[i]; f[++j]='#'; } f[++j]='$'; return j; } int manacher(){ int l=init(); int ma=1,mx=0,id; for(R i=1;i<=l;++i){ if(i<mx) p[i]=min(p[2*id-i],mx-i); else p[i]=1; while(f[i-p[i]]==f[i+p[i]]) p[i]++; if(mx<i+p[i]){ id=i; mx=i+p[i]; } ma=max(ma,p[i]-1); } return ma; } int main() { int cnt=0; while(scanf("%s",s+1)&&s[1]!='E'){ printf("Case %d: %d\n",++cnt,manacher()); } return 0; }