zoukankan      html  css  js  c++  java
  • Manacher算法 求最长回文子串

    Manacher

    引例:P3805 【模板】manacher算法(https://www.luogu.org/problem/P3805)

    题目描述

    给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.

    字符串长度为n

    输入格式

    一行小写英文字符a,b,c...y,z组成的字符串S

    输出格式

    一个整数表示答案

    输入输出样例

    输入 #1
    aaa
    输出 #1
    3

    说明/提示

    字符串长度len <= 11000000

    前为老板的标程int代码

    后为网上巨佬的void代码

     1 #include<stdio.h>
     2 #include<bits/stdc++.h>
     3 using namespace std; 
     4 char st[51000100],s[51000100];
     5 int R[51000100];
     6 int Init()
     7 {
     8     int len = strlen(st);
     9     s[0] = '@';
    10     s[1] = '#';
    11     int j = 2;
    12     for (int i = 0; i < len; i++)
    13     {
    14         s[j++] = st[i];
    15         s[j++] = '#';
    16     }
    17     s[j] = ''; // 末尾添字符串结束符
    18     return j; // 返回修改后的字符串的长度
    19 }
    20 int Manacher()
    21 {
    22     int len = Init(); // 在原串中插入特殊符号,并得到新字符串的长度len
    23     int Ans= -1; // 最长回文长度
    24     int P=0;
    25     int MaxLen = 0;
    26     for (int i = 1; i < len; i++)
    27     {
    28         if (i < MaxLen)R[i] = min(R[2 * P - i], MaxLen-i+1);
    29         else R[i] = 1;
    30         while (s[i - R[i]] == s[i + R[i]])R[i]++; //不用判断边界,在Init()中对边界做了处理
    31         if (MaxLen < i + R[i]-1)
    32         {
    33             P = i;
    34             MaxLen = i + R[i]-1;
    35         }
    36         Ans = max(Ans, R[i] - 1);
    37     }
    38     return Ans;
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%s",st);
    44     cout<<Manacher();
    45 }
    46     
     1 #include<stdio.h>
     2 #include<bits/stdc++.h>
     3 #define maxn 51000100
     4 using namespace std;
     5 int n,hw[maxn],ans;
     6 char a[maxn],s[maxn];
     7 void manacher()
     8 {
     9     int maxright=0,mid;
    10     for(int i=1;i<n;i++)
    11     {
    12         if(i<maxright)
    13             hw[i]=min(hw[(mid<<1)-i],hw[mid]+mid-i);
    14         else
    15             hw[i]=1;
    16         for(;s[i+hw[i]]==s[i-hw[i]];++hw[i]);
    17         if(hw[i]+i>maxright)
    18         {
    19             maxright=hw[i]+i;
    20             mid=i;
    21         }
    22     }
    23 }
    24 void change()
    25 {
    26     s[0]=s[1]='#';
    27     for(int i=0;i<n;i++)
    28     {
    29         s[i*2+2]=a[i];
    30         s[i*2+3]='#';
    31     }
    32     n=n*2+2;
    33     s[n]=0;
    34 }
    35 int main()
    36 {
    37     scanf("%s",a);
    38     n=strlen(a);
    39     change();
    40     manacher();
    41     ans=1;
    42     for(int i=0;i<n;i++)
    43         ans=max(ans,hw[i]);
    44    cout<<ans-1;
    45     return 0; 
    46 }
  • 相关阅读:
    开源 IM 工具编译与环境搭建攻略
    spark研究之install4j打包spark
    OPENFIRE+SPARK语音视频出错连不上的解决办法,倾心吐露:
    Openfire更服务器名称的方法
    install4j打包Spark详解
    关于install4j打包spark的一些方法
    ASP连接LOTUS数据库
    Enabling Large File Uploads On Your Domino Server for XPages
    phpcms v9 数据库操作函数
    phpcms前台的控制器
  • 原文地址:https://www.cnblogs.com/CXYscxy/p/11344784.html
Copyright © 2011-2022 走看看