• manacher模板


    给定一个字符串,要求O(n)时间求出其最长回文串长度。

    首先我们是会O(n^2)的暴力的,就是枚举每个字符作为对称中心,再枚举相同的相邻字符作为对称中心,然后求得答案。

    能不能优化呢?

    我们发现,当一个字符串是回文串时,它满足完全对称,比如:

    abadaba

    设p[i]为以i为中心的回文半径,则p为:

    1 2 1 4 1 2 1

    然后发现右半边竟然可以O(1)出解!

    然后就可以有第一步优化。

    回到上面,按中心分类,回文分为两种。

    能不能将他们都归为满足优化1的那一种?

    答案是能的。在每个字符前后加没有意义的字符,比如 ' # ';

    这就是优化2。

    就有了manacher算法:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char a[51000050],b[51000050];
    int len;
    int p[102000050];
    void manacher()
    {
        int mx = 0,mid =0;
        for(int i=1;i<=((len<<1)|1);i++)
        {
            if(i<mx)p[i] = min(p[2*mid-i],mx-i+1);
            else p[i]=1;
            while(b[i-p[i]]==b[i+p[i]])p[i]++;
            if(i+p[i]-1>mx)
            {
                mx = i+p[i]-1;
                mid = i;
            }
        }
    }
    int main()
    {
        scanf("%s",a+1);
        len = strlen(a+1);
        b[0]='!',b[(len<<1)+2]='^';
        b[1]='#';
        for(int i=1;i<=len;i++)
        {
            b[i<<1] = a[i];
            b[i<<1|1] = '#';
        }
        manacher();
        int ans = 0;
        for(int i=1;i<=((len<<1)|1);i++)
        {
            ans=max(ans,p[i]);
        }
        printf("%d
    ",ans-1);
        return 0;
    }
  • 相关阅读:
    Java多线程初学者指南(5):join方法的使用
    Java多线程初学者指南(4):线程的生命周期
    使用Runnable接口创建线程-3
    用Thread类创建线程-2
    线程简介-1
    Struts, Namespace用法
    多线程编程
    算法实例
    java 堆与栈的区别
    Spring AOP EXPRESSION
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9671487.html
Copyright © 2020-2023  润新知