zoukankan      html  css  js  c++  java
  • Manacher算法+注释

    Manacher算法是用来求一个字符串中最长回文串的算法。

    考虑暴力求最长回文串的做法:

    暴力枚举字符串中的所有字串判断是否回文,然后求最大值。

    时间复杂度O(n^3),考虑优化。

    我们从枚举所有字串改成枚举所有回文串的对称轴,向左右扩展直到不相等,得到最长回文串。

    优化到O(n^2),还是不够优秀。

    于是我们引出Manacher算法。

    先向字符串s中插入特殊字符得到字符串str,这样我们就不用讨论字符串长度是奇是偶了。

    用一个辅助数组p表示每个点可以扩展出去的最长回文长度

    从str[1]扫到str[strlen(str)],再设置两个变量mr表示已触及的最右边的字符,mid表示包含mr的回文串的对称轴位置。

    当i属于(mid,mr)时,显然i关于mid的对称点是(mid<<1)-i(中点坐标公式简单推一下),由于回文串对称串的全等性,我们令p[i]=p[(mid<<1)-i],然后接着尝试扩展:str[i+p[i]]==str[i-p[i]](前后是否对称),p[i]++

    若i>mid,我们就设置mid=i,mr=当前扩展到的最右字符。

    给出代码结束本篇博客

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        int data=0,w=1;char ch=0;
        while(ch!='-' && (ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')w=-1,ch=getchar();
        while(ch>='0' && ch<='9')data=data*10+ch-'0',ch=getchar();
        return data*w;
    }
    const int maxn=5e7+10;
    int n,p[maxn],ans;
    char s[maxn],str[maxn];
    void init(){
        str[0]=str[1]='$';//ccf喜欢这个 
        for(int i=0;i<n;i++)
            str[(i<<1)+2]=s[i],str[(i<<1)+3]='$';
        n=(n<<1)+2;
        str[n]=0;
    }
    void Manacher(){
        int mr=0,mid;
        for(int i=1;i<n;i++){
            if(i<mr)
                p[i]=min(p[(mid<<1)-i],p[mid]+mid-i);
            else p[i]=1;
            for(;str[i+p[i]]==str[i-p[i]];p[i]++);
            if(i+p[i]>mr)
                mr=p[i]+i,mid=i;
        }
    }
    int main(){
        scanf("%s",s);
        n=strlen(s);
        init();Manacher();
        ans=0;
        for(int i=0;i<n;i++)
            ans=max(ans,p[i]);
        printf("%d
    ",ans-1);
        return 0;
    }

    下一篇更新一些数论知识

  • 相关阅读:
    《深入了解 Linq to SQL》之对象的标识 —— 麦叔叔呕心呖血之作
    闲聊吉日与水军
    谈谈需求的变更
    ALinq BUG & 版本发布
    Linq to SQL (ALinq) 也来AOP —— ALinq Inject 博客园首发
    使用Orachard与Bootstrap建站心得
    一位软件作者的吐嘈——读《Google Reader猝死启示录:互联网无法永远免费》有感
    被神化的架构和被夸大的CTRL+C、CTRL+V
    我对程序员技能的一些认识
    又见ORM跑分 —— 对ORM跑分的吐嘈
  • 原文地址:https://www.cnblogs.com/light-house/p/11787641.html
Copyright © 2011-2022 走看看