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;
    }

    下一篇更新一些数论知识

  • 相关阅读:
    win7下的nginx小demo
    破解navicat
    MVC下用C#实现Excel导出
    使用IE10登录,URL出现SessionId的解决办法
    C#错误:The Controls collection cannot be modified
    更改数据库排序规则
    windows server 2008 r2电脑历史操作记录
    jquery easyui无法绑定下拉框内容
    Jquery实现自动提示下拉框
    CLSID {91493441-5A91-11CF-8700-00AA0060263B}错误
  • 原文地址:https://www.cnblogs.com/light-house/p/11787641.html
Copyright © 2011-2022 走看看