字符串的最长回文串长度O(N)算法。
主要是利用了回文串的对称性,利用已有的子串更新答案。
然后拓展答案。
详细讲解还是问dalao吧
我是蒟蒻QAQ
代码(luoguP3805)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using std::min; 5 using std::max; 6 char a[20000000]; 7 int l[100000000]; 8 int f[100000000]; 9 int cnt; 10 int ans; 11 int main() 12 { 13 scanf("%s",a+1); 14 int len=strlen(a+1); 15 l[0]='#'; 16 for(int i=1;i<=len;i++) 17 { 18 l[++cnt]='#'; 19 l[++cnt]=a[i]; 20 } 21 l[++cnt]='#'; 22 23 f[1]=1; 24 int mx=1; 25 for(int i=2;i<=cnt;i++) 26 { 27 f[i]=min(f[mx*2-i],f[mx]+mx-i); 28 while(i+f[i]<=cnt&&l[i+f[i]]==l[i-f[i]]) 29 f[i]++; 30 if(i+f[i]>mx+f[mx]) 31 mx=i; 32 ans=max(ans,f[i]-1); 33 } 34 printf("%d ",ans); 35 return 0; 36 }
poj3974
回文串裸题。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using std::min; 5 using std::max; 6 char a[2000000]; 7 int l[5000000]; 8 int f[5000000]; 9 int mx; 10 int cs; 11 int main() 12 { 13 while(1) 14 { 15 cs++; 16 scanf("%s",a+1); 17 int len=strlen(a+1); 18 if(a[1]=='E') 19 return 0; 20 int cnt=0; 21 l[cnt]='#'; 22 for(int i=1;i<=len;i++) 23 { 24 l[++cnt]='#'; 25 l[++cnt]=a[i]; 26 } 27 mx=1; 28 f[0]=0; 29 f[1]=1; 30 l[++cnt]='#'; 31 int ans=0; 32 for(int i=2;i<=cnt;i++) 33 { 34 f[i]=min(f[mx]+mx-i,f[mx*2-i]); 35 while(i+f[i]<=cnt&&l[f[i]+i]==l[i-f[i]]) 36 f[i]++; 37 if(f[i]+i>f[mx]+mx) 38 mx=i; 39 ans=max(ans,f[i]-1); 40 } 41 printf("Case %d: %d ",cs,ans); 42 } 43 return 0; 44 }