zoukankan      html  css  js  c++  java
  • hdu3068最长回文(manacher)

    好的讲解manacher算法的文章,图文并茂。

    http://blog.csdn.net/ggggiqnypgjg/article/details/6645824

    题解来源:http://blog.sina.com.cn/s/blog_6fa65cf90100s3sg.html

    题意:求给定串的最长回文子串(2009多校题目)

    分析:

    枚举每个点向左向右扩展,看最远能扩展到哪儿.但是普通的枚举是n^2的,肯定超时。现在我们想kmp或扩展kmp一样,给字符串定义一个nex数组,nex[i]表示以i为中心最远能向右扩展的长度,使得s[i – nex[i] + 1……. i + nex[i]- 1]形成的回文。然后我们利用这个数组,在O(n)的时间内求出每个inex[i]。在其他算法中,奇数回文和偶数回文经常给我们带来麻烦,这个算法中,我们第一步要进行的是将每个字符后边(包括开头)加入一个字符(不在串儿的字符集中就行),一般用’#”. 这样就都转换为了奇数的情况。

    例如       abba  (偶)

             改为   #a#b#b#a# (最长为以第3#为中心)

                 aba    (奇) 

    改为    #a#b#a#  (最长为以b为中心)      

    剩下的就是在我们知道了nex[0]…….nex[i – 1] 如何求nex[i] p记录前i-1个字符中以某个字符id为中心最远能向右扩展到的位置。

    // File Name: 3068.cpp
    // Author: Zlbing
    // Created Time: 2013/5/9 13:30:20
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int maxn=2e5;
    char str[maxn],str1[maxn*2];
    int n,ans,nxt[maxn*2];
    void Manacher()
    {
        memset(nxt,0,sizeof(nxt));
        int mx=0,id;
        for(int i=1;i<n;i++)
        {
            if(mx>i)
                nxt[i]=min(nxt[2*id-i],mx-i);
            else nxt[i]=1;
            for(;str1[i-nxt[i]]==str1[i+nxt[i]];nxt[i]++);
            if(i+nxt[i]>mx)
            {
                mx=i+nxt[i];
                id=i;
            }
        }
    }
    void pre()
    {
        int i=0,k=1,t=0;
        str1[0]='$';
        while(str[i]!='\0')
        {
            str1[k++]=t?str[i++]:'#';
            t^=1;
        }
        str1[k++]='#';
        str1[k]='\0';
        n=k;
    }
    int main()
    {
        while(scanf("%s",str)==1)
        {
            pre();
            Manacher();
            int maxx=0;
            for(int i=0;i<n;i++)
                if(maxx<nxt[i]-1)
                    maxx=nxt[i]-1;
            printf("%d\n",maxx);
        }
        return 0;
    }
  • 相关阅读:
    js 笔记
    openstack笔记
    Nginx
    Nginx
    Nginx
    nginx 服务器篇
    Nginx 原理篇
    MySQL 视图、触发器、函数、存储过程
    day41
    MySQL 作业题及答案
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3068801.html
Copyright © 2011-2022 走看看