Poj 3974 manacher

本文介绍了一种使用C++编程语言解决最长回文子串问题的方法,通过预处理字符串并使用Manacher算法高效求解。详细解释了代码逻辑、核心算法原理及实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cccc模拟赛有个 求最长回文子串长度的题,一开始看错题了以为是子序列,雪崩。赛后被告知是manacher,然而暴力也能过,我去。
学了一波,找个例题做一下。

题意:求最长回文子串长度
做法:蛮巧妙的,大致是记录一个maxid(之前回文子串的右端点的最大值)和对应的中心坐标id.每次直接扩展半径至p[2*id-i]和maxid-i之间的较小值,再继续扩展,这样就有效避免了重复比对.有效比对次数是maxid从1至n,是o(n)的.稳得不行.
另,做个预处理,每两个之间插个’#’,头尾分别插个奇怪的字符.这样就能不用讨论奇偶,也不会越界.

贴代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char rec[1000500];
char pro[2001000];
int p[2001000];
int main()
{
    memset(rec,0,sizeof(rec));
    memset(pro,0,sizeof(pro));
    char judge[10]="END";
    int cnt=0;
    while(~scanf("%s",rec))
    {
        cnt++;
        if(!strcmp(judge,rec))break;
        int len=strlen(rec);
        pro[0]='&';
        pro[1]='#';
        pro[2*len+2]='$';
        for(int i=0;i<len;i++)
        {
            pro[2*i+2]=rec[i];
            pro[2*i+3]='#';
        }
        int maxid=0,id=0,M=0;
        for(int i=1;i<=2*len+1;i++)
        {
            if(maxid>i)
            {
                p[i]=min(p[2*id-i],maxid-i+1);
            }
            else{
                p[i]=1;
            }
            while(pro[i+p[i]]==pro[i-p[i]])
            {
                p[i]++;
            }
            if(p[i]+i-1>maxid)
            {
                maxid=p[i]+i-1;
                id=i;
            }
            if(p[i]>M)M=p[i];
        }
        printf("Case %d: %d\n",cnt,M-1);
        memset(rec,0,sizeof(rec));
        memset(pro,0,sizeof(pro));
    }
    return 0;
}

最近忙于各种考试,智商已欠费,什么第二次期中考试我也是服。刷了一些水(对我这种菜鸡都是水的水),我有罪,检讨。mobius反演的东西也看得头大,先放放吧,过段时间再啃。碎片时间也不好开新专题,随便刷刷吧,就酱。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值