目录
初始化以及构造
数组下标从1开始即
cin>>s+1
由于奇回文串和偶回文串某些性质不同,我们首先通过init()
操作使得新串中所有回文串的长度都变成奇数,返回值是新串的长度(原串中的下标i
对应新串中的2i
)
定义数组p[]
,p[i]
表示新串中以下标i
为回文中心的最大回文半径。
新串中每一个下标的i
意味着原串中存在一个的长度是p[i]-1
的回文串
时间复杂度: O ( n ) O(n) O(n)
const int N=2000010;
char s[2*N];
int p[2*N];
int init(char s[])
{
int n=strlen(s+1);
for(int i=2*n;i;i-=2)
{
s[i]=s[i/2];
s[i-1]='*';
}
s[2*n+1]='*';
s[0]='@',s[2*n+2]='&';//哨兵
return 2*n+1;
}
int manacher(int n)// 新串的长度
{
int res=0;
int now=0,mx=0;
for(int i=1;i<=n;i++)
{
p[i]=i<mx?min(p[2*now-i],mx-i):1;
while(s[i+p[i]]==s[i-p[i]]) p[i]++;
if(i+p[i]>mx)
{
mx=i+p[i];
now=i;
}
res=max(res,p[i]-1);//返回最大回文长度
}
return res;
}