zoukankan      html  css  js  c++  java
  • manacher模板

    转自:http://blog.csdn.net/zzkksunboy/article/details/72600679

    作用

    线性时间解决最长回文子串问题。

    思想

    Manacher充分利用了回文的性质,从而达到线性时间。 
    首先先加一个小优化,就是在每两个字符(包括头尾)之间加没出现的字符(如%),这样所有字符串长度就都是奇数了,方便了很多。 
    abcde->#a%b%c%d%e$ 
    记录p[i]表示i能向两边推(包括i)的最大距离,如果能求出p,则答案就是max(p)-1了(以i为中点的最长回文为2*p[i]-1,但这是加过字符后的答案,把加进去的字符干掉,最长回文就是p[i]-1)。

    我们假设p[1~i-1]已经求好了,现在要求p[i]: 
    假设当前能达到的最右边为R,对应的中点为pos,j是i的对称点。 
    1.当i<R时 
    这里写图片描述 
    由于L~R是回文,所以p[i]=p[j](i的最长回文和j的最长回文相同)。 
    这里写图片描述 
    这种情况是另一种:j的最长回文跳出L了。那么i的最长回文就不一定是j的最长回文了,但蓝色的肯定还是满足的。

    综上所述,p[i]=min(p[2*pos-i],R-i)。 
    2.当i>=R时 
    由于后面是未知的,于是只能暴力处理了。

    效率

    但是这样看起来很暴力,为什么复杂度是O(len)的呢?因为R不会减小,每次暴力处理的时候,p[i]增大多少,就说明R增大多少,而R最多增加len次。所以复杂度是O(len)的。

    推论

    (Manchery大神告诉我的,Orz) 
    一个串本质不同的回文子串个数最多为len个,证明方法和效率差不多:每次p[i]增加的时候,就说明出现了新的本质不同的回文子串。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int N=1e6+5;
     7 
     8 int len1,len2;                              //len1为s长度,len2为str长度
     9 int p[N];                                   //p[i]为点i处的最长回文半径
    10 char s[N],str[N];                           //s为原字符串,str为扩充后的字符串
    11 
    12 void init(){
    13     str[0]='$';
    14     str[1]='#';
    15     for(int i=0;i<len1;i++){
    16         str[i*2+2]=s[i];
    17         str[i*2+3]='#';
    18     }
    19     len2=len1*2+2;
    20     str[len2]='%';
    21 }
    22 
    23 void manacher(){
    24     int id=0,mx=0;                          //mx记录回文串延伸的最远位置,id则为对应mx的点,mx=p[id]+id;
    25     for(int i=1;i<len2;i++){
    26         if(mx>i) p[i]=min(p[2*id-i],mx-i);  //点i在mx之内
    27         else p[i]=1;                        //在mx之外则p[i]直接初始化为1
    28         while(str[i+p[i]]==str[i-p[i]])     //暴力匹配
    29             p[i]++;
    30         if(p[i]+i>mx){                      //更新mx,id
    31             mx=p[i]+i;
    32             id=i;
    33         }
    34     }
    35 }
  • 相关阅读:
    WCF 第十一章 工作流服务 处理上下文
    WCF 第十一章 工作流服务 总结
    如何: 连接到一台远程计算机(下)
    WCF 第十一章 工作流服务 从WF暴露一个服务(中)
    WCF 第十一章 工作流服务 从WF暴露一个服务(下)
    WCF 第十一章 工作流服务 从WF暴露一个服务
    [转载]不太规则的迷宫生成算法1
    c# 文件操作
    一些重要的算法
    十个开源的Javascript框架
  • 原文地址:https://www.cnblogs.com/fu3638/p/8504144.html
Copyright © 2011-2022 走看看