Manachar's Algorithm
1、模板
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX=21000020; 4 char s[MAX],t[MAX<<1]; 5 int p[MAX<<1],cnt=0,mid,mr; 6 void manachar() 7 { 8 t[cnt++]='$'; 9 int len=strlen(s); 10 for(int i=0;i<len;i++) 11 { 12 t[cnt++]='#'; 13 t[cnt++]=s[i]; 14 } 15 t[cnt++]='#'; 16 t[cnt]='\0'; 17 18 for(int i=0;i<cnt;i++) 19 { 20 p[i]=i<mr?min(p[(mid<<1)-i],mr-i):1; 21 for(;t[p[i]+i]==t[i-p[i]] and p[i]+i<cnt;p[i]++) 22 if(p[i]+i>mr) 23 { 24 mid=i; 25 mr=p[i]+i; 26 } 27 } 28 } 29 int main() 30 { 31 scanf("%s",s); 32 manachar(); 33 int ans=1; 34 for(int i=0;i<cnt;i++) 35 ans=max(ans,p[i]); 36 printf("%d",ans-1); 37 return 0; 38 }
2、一些结论
1、在往后推maxr时,此时的p[i]就是以maxr为结尾的最长回文串(例题:最长双回文串(有坑))
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX=1e5+10; 4 char pic[MAX],s1[MAX<<1],s2[MAX<<1]; 5 int p1[MAX<<1],p2[MAX<<1],cnt=2; 6 int ans1[MAX<<1] ,ans2[MAX<<1],len; 7 void manachar(char * s,int * p,int * ans) 8 { 9 int mid=0,mr=0; 10 for(int i=0;i<cnt;i++) 11 { 12 p[i]=i<mr?min(p[mid*2-i],mr-i):1; 13 for(;s[p[i]+i]==s[i-p[i]];p[i]++) 14 if(i+p[i]>mr) 15 { 16 mr=i+p[i]; 17 ans[mr]=p[i]; 18 mid=i; 19 } 20 } 21 } 22 int main() 23 { 24 scanf("%s",pic); 25 len=strlen(pic); 26 s1[0]=s2[0]='$'; 27 s1[1]=s2[1]='#'; 28 for(int i=0;i<len;i++) 29 { 30 s1[cnt]=pic[i]; 31 s2[cnt]=pic[len-i-1]; 32 s1[++cnt]='#'; 33 s2[cnt++]='#'; 34 } 35 cnt++; 36 s1[cnt]=s2[cnt]='\0'; 37 manachar(s1,p1,ans1); 38 manachar(s2,p2,ans2); 39 int j=cnt-4,ans=2; 40 for(int i=3;i<cnt-2;i++) 41 { 42 if(s1[i]=='#') 43 ans=max(ans,ans1[i]+ans2[j]); 44 j--; 45 } 46 cout<<ans<<endl; 47 return 0; 48 }
2、