(注意:本博客只作为模板,不适合刚学manacher的人看)
(几个关键点大概可以表示成这样)
(ct-p[ct]----j---ct---i----ct+p[ct])
(因为p[i]<=p[j],所以p[i]=min(p[2ct-i],ct+p[ct]-i))
#include <bits/stdc++.h>
using namespace std;
const int maxn=51000100;
int n,p[maxn],ans;
char a[maxn],s[maxn<<1];
void init()
{
s[0]=s[1]='#';
for(int i=0;i<n;i++)
{
s[i*2+2]=a[i];
s[i*2+3]='#';
}
n=n*2+2;
s[n]=0;
}
int manacher()
{
int maxright=0,ct,ans=0;
for(int i=1;i<n;i++)
{
if(i<maxright) p[i]=min(p[ct*2-i],p[ct]+ct-i);
//----j----ct----i----ct+p[ct]
//可知j=ct*2-i,但是p[i]最大是(p[ct]+ct)-i
else p[i]=1;
for(;s[i+p[i]]==s[i-p[i]];++p[i])
if(p[i]+i>maxright) maxright=p[i]+i,ct=i;
ans=max(ans,p[i]);
}
return ans-1;
}
int main()
{
cin>>a;
n=strlen(a);
init();
cout<<manacher();
}
(color{Orange}{附上一道练手题,cf的})
#include <bits/stdc++.h>
using namespace std;
string Manacher(const string &s){
string t="#";
for(char c:s) t+=c,t+="#";
int RL[t.size()]={0};
int MaxRight=0;
int pos=0;
for(int i=0;i<t.size();i++){
if(i<MaxRight)
RL[i]=min(RL[2*pos-i],MaxRight-i);
else
RL[i]=1;
while(i-RL[i]>=0&&i+RL[i]<t.size()&&t[i-RL[i]]==t[i+RL[i]])
RL[i]+=1;
if(RL[i]+i-1>MaxRight)
pos=i,MaxRight=RL[i]+i-1;
}
int MaxLen=0;
for(int i=0;i<t.size();i++)
if(RL[i]==i+1)
MaxLen=i;
return s.substr(0,MaxLen);
}
void solve(){
string s;cin>>s;
int l=0,r=s.size()-1;
while(l<r&&s[l]==s[r]) ++l,--r;
string s1=s.substr(l,r-l+1);
string s2=s1;
reverse(s2.begin(),s2.end());
s1=Manacher(s1);
s2=Manacher(s2);
cout<<s.substr(0,l)<<(s1.size()>s2.size()?s1:s2)<<s.substr(r+1)<<"
";
}
int main()
{
int t;cin>>t;
while(t--)
solve();
return 0;
}