manacher

算法流程
我们要计算\(i+k\)这个点的回文串,\(i\)这个点是\(i+l[i]\)最大的点,也就是能达到的最远的点
当我们计算\(i+k\)这个点没有在最远到达点之前,暴力扩展
被包含的话,分情况讨论

i-k 回文串有一部分在 i 的回文串之外
这种情况p[i+k]=p[i]-k
这时候就有人会有疑惑了,p[i-k]那里的长度比你上面上的p[i]-k要长呀 ?
很正确虽然p[i-k]的长度长,但是p[i]的延伸最终在那里终止了
就说明i+p[i]和i-p[i]是不相同的两个符号,所以p[i+k]的长度最多只是p[i]-k

i-k的回文串全部在p[i]之内,所以p[i+k]=p[i-k]
那么这时的p[i+k]会不会更长呢,不可能

i-k的右端和i的右端重合,这时候 p[i+k]最小是p[i]-k;并且
可能继续增加
-----出自57级shenben学长

#include <iostream>
#include <cstring>
#include <algorithm> 
#include <cstdio>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=11000007;
char S[maxn<<1],s[maxn];
int n,l[maxn<<1];
int main()
{
    scanf("%s",s+1);
    int n=strlen(s+1);
    int i=0,len=1;
    S[0]='@';S[1]='#';
    while(i<=n) S[++len]=s[++i],S[++len]='#'; 
    int ma=0,id=0,ans=0;
    FOR(i,1,len) {
        if(ma > i) l[i]=min(ma-i,l[id*2-i]);
        else l[i]=1;
        while(S[i+l[i]]==S[i-l[i]]) l[i]++;
        if(ma < i+l[i]-1) id=i,ma=i+l[i]-1;
        ans=max(ans,l[i]-1);
    }
    cout<<ans<<"\n";
    return 0;
}
全部评论

相关推荐

2024-12-27 10:21
已编辑
海南师范大学 媒介策划
到我怀里来:身高体重住址这些就别写了,留几个关键的就行,工作经历突出重点写详细点
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务