zoukankan      html  css  js  c++  java
  • manacher

    算法流程
    我们要计算(i+k)这个点的回文串,(i)这个点是(i+l[i])最大的点,也就是能达到的最远的点
    当我们计算(i+k)这个点没有在最远到达点之前,暴力扩展
    被包含的话,分情况讨论

    i-k 回文串有一部分在 i 的回文串之外
    这种情况p[i+k]=p[i]-k
    这时候就有人会有疑惑了,p[i-k]那里的长度比你上面上的p[i]-k要长呀 ?
    很正确虽然p[i-k]的长度长,但是p[i]的延伸最终在那里终止了
    就说明i+p[i]和i-p[i]是不相同的两个符号,所以p[i+k]的长度最多只是p[i]-k

    i-k的回文串全部在p[i]之内,所以p[i+k]=p[i-k]
    那么这时的p[i+k]会不会更长呢,不可能

    i-k的右端和i的右端重合,这时候 p[i+k]最小是p[i]-k;并且
    可能继续增加
    -----出自57级shenben学长

    #include <iostream>
    #include <cstring>
    #include <algorithm> 
    #include <cstdio>
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int maxn=11000007;
    char S[maxn<<1],s[maxn];
    int n,l[maxn<<1];
    int main()
    {
    	scanf("%s",s+1);
    	int n=strlen(s+1);
    	int i=0,len=1;
    	S[0]='@';S[1]='#';
    	while(i<=n) S[++len]=s[++i],S[++len]='#'; 
    	int ma=0,id=0,ans=0;
    	FOR(i,1,len) {
    		if(ma > i) l[i]=min(ma-i,l[id*2-i]);
    		else l[i]=1;
    		while(S[i+l[i]]==S[i-l[i]]) l[i]++;
    		if(ma < i+l[i]-1) id=i,ma=i+l[i]-1;
    		ans=max(ans,l[i]-1);
    	}
    	cout<<ans<<"
    ";
    	return 0;
    }
    
  • 相关阅读:
    Linux常用命令整理
    Linux脚本无法进入目录
    mysql5.7.初始化后,临时密码过期
    通过scp 命令向远程Linux服务器传输文件
    Linux进入单用户模式修改root密码
    Kali Linux安装谷歌输入法
    kali 安装pip命令
    CentOS 7 防火墙设置
    CentOS7 安装python 3.7
    CentOS 7安装完成之后无法联网
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9911778.html
Copyright © 2011-2022 走看看