zoukankan      html  css  js  c++  java
  • Manacher算法总结

    之前队爷讲的时候没听懂,今天考试考到了,花时间学习一下。

    推荐这篇博客,讲的很详细;

    题目: LGOJ[P3805]Manacher模板

    求最长回文子串

    1.BF思路:

    O(n)枚举对称点,再利用回文的性质向两边扩展,总复杂度O(n2)

    这太不优秀了QAQ

    2.可以改进的地方

    之前的算法主要是枚举了重复的子串

    栗子:

    s="a b a b a a"

     i : 1 2 3 4 5 6

    >在i=3时会扩展到"a b a b a"(ps:黑体为当前对称点,以后不再说明)

    >而子串"a b a"在i=2时就已经被访问过了

    如何避免呢?

    3.马拉车Manacher算法:

    正如上面所说,我们要避免重复的扩展,也就是要利用已有的信息

    这里我们就要充分利用回文串的性质了

    下面的栗子应该可以给你一些启发:

      串S为已经扩展完的回文串,长度为len,对称点为mid(方便起见,假设S为一个长度为奇数的串)

      (S_1,S_2,S_3...S_{mid},S_{mid+1},...,S_{len-1},S_{len})

      用数组(r_i)记录以i为对称点的最长回文子串半径

      因为S是回文串,所以(S_i=S_{mid*2-i}(1<=i<=mid-1))

      假如我们现在已经知道了(r_a(a<mid)),那么(r_b(b为a的对称点))可以直接推出

      为什么呢?

      因为S串回文,

      所以,在S串上位置相对的两段子串一定是对称的

      于是就可以利用左边的信息来更新右边的信息了

    这基本上就是manacher的思路


    盗一波图:(主要是解释程序)

    ①其实左边的红格没啥用

    ②浅色的格子为i,j的回文子串

    ③RL就是r

    >在这里虽然rj很长,但是在大于Max_Right的部分你并不知道满不满足i子串回文(因为在Max_Right以右并不满足回文串的性质),所以ri只能到Max_Right处

    上代码

     1 #include<bits/stdc++.h>
     2 #define R register int 
     3 using namespace std;
     4 string s;
     5 char c[40000007];
     6 int ls,r[40000007];
     7 int main()
     8 {
     9     cin>>s;
    10     ls=s.length();
    11     R len=0;
    12     c[++len]='!',c[++len]='#';
    13 for(R i=0;i<ls;i++) 14 { 15 c[++len]=s[i]; 16 c[++len]='#'; 17 }//这样处理后不用判回文串长度奇偶(c为转换后的串) 18 R Max_Right=0,mid=0;//mid就是图中的pos 19 for(R i=1;i<=len;i++) 20 {//Max_Right是一个重要的边界,它的右边是从未触及过的点 21 if(i>Max_Right)r[i]=1;//图①(之前从未到过i,只能老老实实地往后扩展) 22 else r[i]=min(r[mid*2-i],Max_Right-i);//图②,③(分类讨论了rj与Max_Right-mid的大小关系)以及栗子的结论 23 for(;c[i+r[i]]==c[i-r[i]]&&i+r[i]<=len&&i-r[i]>0;++r[i]);//在②的浅色格或是③的蓝线两边两边继续拓展 24 if(i+r[i]>Max_Right)//更新 25 { 26 Max_Right=r[i]+i; 27 mid=i; 28 } 29 } 30 R ans=0; 31 for(R i=1;i<=len;i++) 32 { 33 ans=max(ans,r[i]);//可以发现此时新串的半径即为原串的长度 34 } 35 cout<<ans-1<<endl; 36 return 0; 37 }

     我水平实在是太差了,以上内容不保证正确(qaq)

    如果写的有问题请在评论指出!谢谢!

      

      

  • 相关阅读:
    Mac idea 打不开
    git学习之git reset命令
    更改 macOS 用户帐户和个人文件夹的名称
    SpringBoot系列: 如何优雅停止服务
    windows环境下启动mongodb服务
    rocketMq4.2.0启动broker报错找不到或无法加载主类 FilesJavajdk1.8.0_101libdt.jar;C:Program]
    初创公司与成熟的公司各有什么利弊?有5年工作经验的人适合进那一个?(行业职位是一样的情况下)
    mac 10.15 国内如何安装brew
    Mac下SSH Key配置
    买苹果MacBook Pro ,有必要买care吗?
  • 原文地址:https://www.cnblogs.com/Zenyz/p/9838646.html
Copyright © 2011-2022 走看看