1. 程式人生 > >HDU 3068 最長迴文(Manacher)

HDU 3068 最長迴文(Manacher)

Description
給出一個只由小寫英文字元a,b,c…y,z組成的字串S,求S中最長迴文串的長度.
迴文就是正反讀都是一樣的字串,如aba, abba等
Input
輸入有多組case,不超過120組,每組輸入為一行小寫英文字元a,b,c…y,z組成的字串S
兩組case之間由空行隔開(該空行不用處理)
字串長度len <= 110000
Output
每一行一個整數x,對應一組case,表示該組case的字串中所包含的最長迴文長度.
Sample Input
aaaa

abab
Sample Output
4
3
Solution
Manacher求最長迴文子串裸題
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
//Manacher求最長迴文子串,時間複雜度O(n) 
#define maxn 111111 
char ss[2*maxn];
int ma[2*maxn];
void Manacher(char *s,int len)
{
    int l=0;
    ss[l++]='$';
    ss[l++]='#';
    for(int i=0;i<len;i++)
    {   
        ss[l++]=s
[i]; ss[l++]='#'; } ss[l]=0; int mx=0,id=0; for(int i=0;i<l;i++) { ma[i]=mx>i?min(ma[2*id-i],mx-i):1; while(ss[i+ma[i]]==ss[i-ma[i]])ma[i]++; if(i+ma[i]>mx) { mx=i+ma[i]; id=i; } } } char s[maxn]; int
main() { while(~scanf("%s",s)) { int len=strlen(s); Manacher(s,len); int ans=0; for(int i=0;i<2*len+2;i++) ans=max(ans,ma[i]-1); printf("%d\n",ans); } return 0; }