Manacher回文串算法 hdu3068 hdu4513
学习资料:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824
时间复杂度O(N)
模板:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void Manacher(int n) 2 { 3 int i; 4 int mx=0;//记录前面回文串最长影响到的地方。不一定是最长回文串造成的。 5 int id;//最长影响串的ID; 6 p[0]=0; 7 for(i=1;i<n;i++) 8 { 9 p[i]=1;//至少是1 10 if(mx>i)//i受到影响即,id+p[id]-1>=i; 11 { 12 p[i]=p[2*id-i];//2*id-i是i关于id的对称点相当于是id-(i-id); 13 if(mx-i<p[i])p[i]=mx-i; 14 //由于对称点的回文半径可能超过mx-i,因为mx后面的还没有配过 15 //所以要取小的。等等继续配 16 } 17 18 //向两端配匹 19 while(str[i-p[i]]==str[i+p[i]])p[i]++; 20 21 if(i+p[i]>mx) 22 { 23 mx=i+p[i]; 24 id=i; 25 } 26 } 27 }
hdu3068:求一个字符串的最长回文子串,就是一个满足本身是回文的最长的子串
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 const int M = 110010; 4 char s[M],str[M*2]; 5 int p[M*2]; 6 int n; 7 int max(int a,int b){ 8 return a>b?a:b; 9 } 10 int min(int a,int b){ 11 return a<b?a:b; 12 } 13 void init(){ 14 int i,j=0; 15 n=strlen(s); 16 str[j++]='$';str[j++]='#'; 17 for(i=0;i<n;i++){ 18 str[j++]=s[i]; 19 str[j++]='#'; 20 } 21 str[j]='\0'; 22 n=j; 23 } 24 int solve(){ 25 int i,id,mx=0; 26 for(i=1;i<n;i++){ 27 if(mx>i) p[i]=min(mx-i,p[2*id-i]); 28 else p[i]=1; 29 for(;str[i+p[i]]==str[i-p[i]];p[i]++) ; 30 if(p[i]+i>mx){ 31 mx=p[i]+i; 32 id=i; 33 } 34 } 35 int res=0; 36 for(i=1;i<n;i++) 37 res=max(res,p[i]); 38 return res; 39 } 40 int main(){ 41 while(scanf("%s",&s)!=EOF){ 42 init(); 43 printf("%d\n",solve()-1); 44 } 45 return 0; 46 }
hdu4513:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 const int M = 100010; 4 int s[M],str[M*2]; 5 int p[M*2]; 6 int T,n; 7 int max(int a,int b){ 8 return a>b?a:b; 9 } 10 int min(int a,int b){ 11 return a<b?a:b; 12 } 13 void init(){ 14 int i,j=0; 15 str[j++]=-1;str[j++]=0; 16 for(i=0;i<n;i++){ 17 str[j++]=s[i]; 18 str[j++]=0; 19 } 20 n=j; 21 } 22 int solve(){ 23 int i,id,mx=0; 24 for(i=1;i<n;i++){ 25 if(mx>i) p[i]=min(mx-i,p[2*id-i]); 26 else p[i]=1; 27 while(str[i+p[i]]==str[i-p[i]]){ 28 if(str[i+p[i]]<10) p[i]++; 29 else { 30 int a=i-p[i]; 31 int b=i+p[i]; 32 33 if(a+2<=b-2&&str[a]<=str[a+2]&&str[b-2]>=str[b]){ 34 p[i]++; 35 continue; 36 } 37 else if(a==b){ 38 p[i]++; 39 continue; 40 } 41 else if(a+2>b-2){ 42 p[i]++; 43 continue; 44 } 45 break; 46 } 47 } 48 if(p[i]+i>mx){ 49 mx=p[i]+i; 50 id=i; 51 } 52 } 53 int res=0; 54 for(i=2;i<n;i++) 55 res=max(res,p[i]); 56 return res; 57 } 58 int main(){ 59 int i; 60 scanf("%d",&T); 61 while(T--){ 62 scanf("%d",&n); 63 for(i=0;i<n;i++){ 64 scanf("%d",&s[i]); 65 } 66 init(); 67 printf("%d\n",solve()-1); 68 } 69 return 0; 70 }