HDu 3068最長回文Manacherアルゴリズム
クリックしてリンクを開く
リファレンス
Manacherはマッチングした最右位置と対応する対称中心利用と対称性を記録することによっていくつかの無駄な比較をスキップする.
リファレンス
Manacherはマッチングした最右位置と対応する対称中心利用と対称性を記録することによっていくつかの無駄な比較をスキップする.
#include
#include
#include
#include
using namespace std;
const int M =111000;
char s[M];
char t[2*M]; //
int p[2*M];// p[i] i
int len;
void Init()
{
int i;
len=strlen(s);
t[0]='@';//
for(int i=1;i<=2*len;i+=2)
{
t[i]='#';
t[i+1]=s[i/2];
}
t[2*len+1]='#';//
t[2*len+2]='$';//
t[2*len+3]=0;//
len=2*len+1;//
}
void MANACHER()
{
int mx=0,ans=0,po=0;// i p po po mx
for(int i=1;i<=len;i++)
{
if(mx>i)
{
p[i]=min(p[2*po-i],mx-i); // i po (i+j)/2=po j=2*po-i
// 1 j-len[j]~~i+len[j] po -> lem[i]>=len[j] ( )
// 2 i+len[j]>mx i-(mx-i)~~i+(mx-i) mx ( )
}
else
{
p[i]=1;//mx
}
while(t[i-p[i]]==t[i+p[i]])
p[i]++;
if(p[i]+i>mx)//update
{
mx=p[i]+i;
po=i;
}
ans=max(ans,p[i]);
}
ans-=1;// 2*p[i]-1 '#' 1 ( ) x+(x-1)==2*p[i]-1 x=p[i] p[i]-1
printf("%d
",ans);
}
int main()
{
while(scanf("%s",s)!=EOF)
{
Init();
MANACHER();
}
return 0;
}