P3805 【模板】manacher算法
manacher
manacher算法:线性时间处理字符串中的最长回文串长度
#include<iostream> #include<cstdio> #include<cstring> #include<cctype> using namespace std; template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;} template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;} char a[11000003],b[22000008]; int p[22000008],n,ans;//p[i]:点i可扩展的最长回文串长度 int main(){ scanf("%s",a); int len=strlen(a); for(int i=0;i<len;++i) b[n++]='#',b[n++]=a[i]; //在每个字符间插入一个特殊字符,同时处理长度为奇/偶的回文串 b[n++]='#'; int mx=-1,id=0; mx:目前处理出可拓展到右端点最右的回文串的右端点;id:右端点最右的回文串的中心 for(int i=0;i<n;++i){ p[i]= i<mx ? min(p[id*2-i],mx-i+1):1; //id*2-i: i关于id的对称点 while(i+p[i]<n&&i-p[i]>=0&&b[i+p[i]]==b[i-p[i]]) ++p[i]; if(i+p[i]-1>mx) mx=i+p[i]-1,id=i; //更新右端点最右的标记 ans=max(ans,p[i]-1); //注意长度为p[i]-1(要去掉特殊字符) }printf("%d",ans); return 0; }