manacher
馬拉車算法說白了就是遞推進行優化求迴文串的算法
就是求p數組,表示以以i爲中心的最長迴文串的半徑
核心就是mx和id的使用
主要分爲三個部分
1.要求的i在mx內部
.以i的對稱點爲中心的迴文串完全包含在以id爲中心的迴文串中
p[i]=p[2*id-i];
.超出了id爲中心的迴文串邊界
p[i]=mx-i+1;
2.i在以id爲中心的迴文串之外
p[i]=1;
當然這樣求得的p[i]可能不是最大的,再來一個while看能不能加長就好了
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<bits/stdc++.h>
using namespace std;
const int maxn=110000;
int p[maxn*2+5];//p數組記錄的是以i爲中心的迴文串的半徑,包括i那一位置。
string s,s_new;
void Init()
{
fill(p,p+maxn,0);
}
int Getnew()
{
int len=s.size();
s_new="$#";//這裏要從下標是1的位置開始,以防數組越界
for(int i=0;i<len;i++)
{
s_new+=(s[i]);
s_new+="#";
}
}
int Manacher(){
Getnew();
int len=s_new.size();
int mx=1,id=1;//右邊界最大的迴文串的中心點id和邊界
int maxlen=1;//記錄最長迴文串的長度
for(int i=1;i<len;i++)
{
if(i<=mx)//i在右邊界之內
{
if(mx-i+1>=p[2*id-i]) //以i的對稱點爲中心的迴文串完全包含在以id爲中心的迴文串中
{
p[i]=p[2*id-i];
}
else//超出了id爲中心的迴文串邊界
{
p[i]=mx-i+1;
}
}
else//i在以id爲中心的迴文串之外
{
p[i]=1;
}
while(s_new[i-p[i]]==s_new[i+p[i]])
{
++p[i];
}
if(mx<i+p[i]-1)
{
mx=i+p[i]-1;
id=i;
}
maxlen=max(maxlen,p[i]);
}
return maxlen-1;
}
int main()
{
cout<<s<<endl;
int k=Manacher();
cout<<k<<endl;
}