使用o(n)的manacher算法,详见代码
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<math.h> 5 #include<string.h> 6 #include<vector> 7 #include<queue> 8 #include<iterator> 9 #include<vector> 10 #include<set> 11 #define dinf 0x3f3f3f3f 12 typedef long long ll; 13 //const int Max=(1<<16)+10; 14 using namespace std; 15 #define SIZE 1000005 16 17 18 char tmp[SIZE],s[SIZE];//tmp存变换后的串,s存原串 19 int p[SIZE];//存以mid为中心的回文串的长度 20 21 22 void init() 23 { 24 int slen=strlen(s); 25 tmp[0]=‘$‘; //头标记防止越界 26 for(int i=1,j=0;i<=2*slen+1;i+=2) 27 { 28 tmp[i]=‘#‘; 29 tmp[i+1]=s[j++]; 30 } 31 tmp[2*slen+2]=‘#‘;//尾标记 32 } 33 34 int manacher() 35 { 36 int mid=0,mx=0,ans=0;//mx为当前计算回文串最右边字符位置最大值 37 int tlen=strlen(s)*2+1; 38 for(int i=1;i<=tlen;i++) 39 { 40 if(mx>i) 41 p[i]=min(mx-i,p[2*mid-i]); 42 else //i>mx从头开始匹配 43 p[i]=1; 44 while(tmp[i-p[i]]==tmp[i+p[i]]) 45 p[i]++; 46 if(p[i]+i>mx)//计算得到的右端点值大于mx则进行更新 47 { 48 mx=p[i]+i; 49 mid=i; 50 } 51 ans=max(ans,p[i]); 52 } 53 return ans-1;//p[i]-1即最长回文串的长度 54 } 55 56 int main() 57 { 58 while(scanf("%s",&s)!=EOF) 59 { 60 init(); 61 printf("%d\n",manacher()); 62 } 63 return 0; 64 }
时间: 2024-10-02 15:15:03