manacher 模板
求最长回文子序列的 O(n)做法
讲解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int MAXN=11000117;
char s[MAXN],snew[MAXN*2+5];
int p[MAXN*2+5];
int init(){
int len=strlen(s);
snew[0]='&';snew[1]='#';
int j=2;
for(int i=0;i<len;i++){
snew[j++]=s[i];
snew[j++]='#';
}
snew[j]='\0';
return j;
}
int manacher(){
int ans=0;
int len=init();
int id=0,mx=0;
for(int i=1;i<len;i++){
if(i<mx) p[i]=min(p[id*2-i],mx-i);
else p[i]=1;
while(snew[i-p[i]]==snew[i+p[i]]) p[i]++;//注意这里的循环写在if外面,因为如果p[i]+i==mx,还可以向外扩展
if(i+p[i]>mx){
mx=i+p[i];
id=i;
}
ans=max(ans,p[i]-1);
}
return ans;
}
int main(){
freopen("in.txt","r",stdin);
scanf("%s",s);
printf("%d",manacher());
fclose(stdin);
return 0;
}