目的:线性查找一个串的最长回文子串

时间复杂度:O(n)

len[i]表示以i为中心的回文串的半径,mx即为当前计算回文串最右边字符的最大值,p是中心点mid,mx-i和2*p-1关于p对称

https://blog.csdn.net/csdn_kou/article/details/82917937

hdu3068,板子题,求最长回文长度。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=;
  4. int t,len[maxn*];
  5. char S[maxn*],T[maxn*],s[maxn*];
  6.  
  7. int init(char *str)
  8. {
  9. int n=strlen(str);
  10. for(int i=,j=;i<=*n;j++,i+=)
  11. {
  12. s[i]='#';
  13. s[i+]=str[j];
  14. }
  15. s[]='$';
  16. s[*n+]='#';
  17. s[*n+]='@';
  18. s[*n+]='\n';
  19. return *n+;
  20. }
  21. void manacher(int n)
  22. {
  23. int mx=,p=;
  24. for(int i=;i<=n;i++)
  25. {
  26. if(mx>i)len[i]=min(mx-i,len[*p-i]);
  27. else len[i]=;
  28. while(s[i-len[i]]==s[i+len[i]])len[i]++;
  29. if(len[i]+i>mx)mx=len[i]+i,p=i;
  30. }
  31. }
  32.  
  33. int main()
  34. {
  35. while(scanf("%s",S)!=EOF)
  36. {
  37. int Len=strlen(S),n=init(S);
  38. for(int i=;i<=n;i++)len[i]=;
  39. manacher(n);
  40.  
  41. int ans=;
  42. for(int i=;i<=n;i++)
  43. {
  44. ans=max(ans,len[i]-);
  45. }
  46. printf("%d\n",ans);
  47. }
  48. return ;
  49. }

2019徐州G colorful string,求所有回文子串的value之和,一个串的value为串中字母种类,dfs预处理了第i位前一个a-z的位置,复杂度26*n。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int maxn=3e5+;
  5. int t,len[maxn*];
  6. char S[maxn*],T[maxn*],s[maxn*];
  7.  
  8. int init(char *str){
  9. int n=strlen(str);
  10. for(int i=,j=;i<=*n;j++,i+=){
  11. s[i]='#';
  12. s[i+]=str[j];
  13. }
  14. s[]='$';
  15. s[*n+]='#';
  16. s[*n+]='@';
  17. s[*n+]='\n';
  18. return *n+;
  19. }
  20.  
  21. void manacher(int n)
  22. {
  23. int mx=,p=;
  24. for(int i=;i<=n;i++){
  25. if(mx>i) len[i]=min(mx-i,len[*p-i]);
  26. else len[i]=;
  27. while(s[i-len[i]]==s[i+len[i]]) len[i]++;
  28. if(len[i]+i>mx) mx=len[i]+i,p=i;
  29. }
  30. }
  31.  
  32. int dp[maxn*][],place[];
  33. int main()
  34. {
  35. scanf("%s",S);
  36. int Len=strlen(S),n=init(S);
  37. for(int i=;i<=n;i++)len[i]=;
  38. manacher(n);
  39.  
  40. ll ans=;
  41. int k=;
  42. for(int i=;i<;i++)place[i]=-;
  43. for(int i=;i<=n;i++)
  44. {
  45. if(i%==)place[S[k++]-'a']=i;
  46. for(int j=;j<;j++)dp[i][j]=place[j];
  47. }
  48.  
  49. for(int i=;i<=n;i++)
  50. {
  51. for(int j=;j<;j++)
  52. {
  53. if(i-dp[i][j]<len[i])
  54. {
  55. ans+=1ll*(len[i]-(i-dp[i][j]))/;
  56. }
  57. }
  58. }
  59. printf("%lld\n",ans);
  60.  
  61. return ;
  62. }

hdu3613,一个串割成两个串,如果是回文串则val为所有字母val之和,否则为零。

字母的val题目给出,求使总串的val最高的割法的val值。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=5e5+;
  4. int t,len[maxn<<];
  5. char S[maxn<<],T[maxn<<],s[maxn<<];
  6.  
  7. int init(char *str)
  8. {
  9. int n=strlen(str);
  10. for(int i=,j=;i<=*n;j++,i+=)
  11. {
  12. s[i]='#';
  13. s[i+]=str[j];
  14. }
  15. s[]='$';
  16. s[*n+]='#';
  17. s[*n+]='@';
  18. s[*n+]='\n';
  19. return *n+;
  20. }
  21. void manacher(int n)
  22. {
  23. int mx=,p=;
  24. for(int i=;i<=n;i++)
  25. {
  26. if(mx>i)len[i]=min(mx-i,len[*p-i]);
  27. else len[i]=;
  28. while(s[i-len[i]]==s[i+len[i]])len[i]++;
  29. if(len[i]+i>mx)mx=len[i]+i,p=i;
  30. }
  31. }
  32.  
  33. int main()
  34. {
  35. int T;
  36. scanf("%d",&T);
  37. while(T--)
  38. {
  39. int val[]={};
  40. for(int i=;i<;i++)scanf("%d",&val[i]);
  41. cin>>S;
  42. int Len=strlen(S),n=init(S);
  43. for(int i=;i<=n;i++)len[i]=;
  44. manacher(n);
  45.  
  46. int lg=,rg=,ans=;
  47. for(int i=;i<Len;i++)rg+=val[S[i]-'a'];
  48. for(int i=;i<=n;i++)
  49. {
  50. if(i%==)
  51. {
  52. lg+=val[s[i]-'a'];
  53. rg-=val[s[i]-'a'];
  54. }
  55. else
  56. {
  57. int l=,r=*Len+,tmplg=,tmprg=;
  58. if(i!=l&&i!=r)
  59. {
  60. int mid1=(l+i)>>,mid2=(i+r)>>;
  61. if(len[mid1]==mid1-l+)tmplg=lg;
  62. if(len[mid2]==r-mid2+)tmprg=rg;
  63. ans=max(ans,tmplg+tmprg);
  64. }
  65. }
  66. }
  67. printf("%d\n",ans);
  68. }
  69. return ;
  70. }

hdu3294,求最早出现的最长回文串的l、r区间,并且转换后输出

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=2e5+;
  4. int t,len[maxn<<];
  5. char S[maxn<<],T[maxn<<],s[maxn<<];
  6. int init(char *str)
  7. {
  8. int n=strlen(str);
  9. for(int i=,j=;i<=*n;j++,i+=)
  10. {
  11. s[i]='#';
  12. s[i+]=str[j];
  13. }
  14. s[]='$';
  15. s[*n+]='#';
  16. s[*n+]='@';
  17. s[*n+]='\n';
  18. return *n+;
  19. }
  20. void manacher(int n)
  21. {
  22. int mx=,p=;
  23. for(int i=;i<=n;i++)
  24. {
  25. if(mx>i)len[i]=min(mx-i,len[*p-i]);
  26. else len[i]=;
  27. while(s[i-len[i]]==s[i+len[i]])len[i]++;
  28. if(len[i]+i>mx)mx=len[i]+i,p=i;
  29. }
  30. }
  31.  
  32. int main()
  33. {
  34. char ch;
  35. while(scanf("%c %s",&ch,S)!=EOF)
  36. {
  37. int Len=strlen(S),n=init(S);
  38. for(int i=;i<=n;i++)len[i]=;
  39. manacher(n);
  40.  
  41. int ans=,l=,r=;
  42. for(int i=;i<=n;i++)
  43. {
  44. if(len[i]->ans)
  45. {
  46. ans=len[i]-;
  47. l=(i-len[i]+)/;
  48. r=(i+len[i]-)/;
  49. }
  50. }
  51. if(ans<)printf("No solution!\n");
  52. else
  53. {
  54. printf("%d %d\n",l,r);
  55. for(int i=l;i<=r;i++)
  56. {
  57. S[i]=S[i]-ch+'a';
  58. if(S[i]>'z')S[i]=S[i]-'z'+'a'-;
  59. if(S[i]<'a')S[i]=S[i]+'z'-'a'+;
  60. }
  61. S[r+]='\0';
  62. printf("%s\n",S+l);
  63. }
  64. getchar();
  65. }
  66. return ;
  67. }

hdu4513,最长递增(不降)回文串,manacher里只需要改个while

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=1e5+;
  4. int t,len[maxn*];
  5. int s[maxn*],T[maxn*],S[maxn*];
  6.  
  7. int init(int *str,int n)
  8. {
  9. for(int i=,j=;i<=*n;j++,i+=)
  10. {
  11. s[i]=-;
  12. s[i+]=str[j];
  13. }
  14. s[]=-;
  15. s[*n+]=-;
  16. s[*n+]=-;
  17. return *n+;
  18. }
  19. void manacher(int n)
  20. {
  21. int mx=,p=;
  22. for(int i=;i<=n;i++)
  23. {
  24. if(mx>i)len[i]=min(mx-i,len[*p-i]);
  25. else len[i]=;
  26. while(s[i-len[i]]==s[i+len[i]]&&s[i-len[i]]<=s[i-len[i]+])len[i]++;
  27. if(len[i]+i>mx)mx=len[i]+i,p=i;
  28. }
  29. }
  30.  
  31. int main()
  32. {
  33. int T;
  34. scanf("%d",&T);
  35. while(T--)
  36. {
  37. int n;
  38. scanf("%d",&n);
  39. for(int i=;i<n;i++)
  40. scanf("%d",&S[i]);
  41. int Len=n,len2=init(S,n);
  42. for(int i=;i<=n;i++)len[i]=;
  43. manacher(len2);
  44.  
  45. int ans=;
  46. for(int i=;i<=len2;i++)
  47. {
  48. ans=max(ans,len[i]-);
  49. }
  50. printf("%d\n",ans);
  51. }
  52. return ;
  53. }

...

马拉车manacher的更多相关文章

  1. 51nod 1595 回文度 | 马拉车Manacher DP

    51nod 1595 回文度 题目描述 如果长度为n的字符串是一个回文串,同时它的长度为floor(n/2)的前缀和后缀是K-1度回文串,则这个字符串被称为K度回文串.根据定义,任何字符串(即使是空字 ...

  2. HDU - 3068 最长回文(马拉车Manacher)题解

    思路:马拉车裸题,我们用一个p[i]数组代表以i为中心的最大回文半径.这里用了一个小技巧,如果一个串是aaaa这样的,那我们插入不相干的字符使它成为#a#a#a#a#,这样无论这个串是奇数还是偶数都会 ...

  3. hdu3068-最长回文-马拉车(Manacher)算法

    http://acm.hdu.edu.cn/showproblem.php?pid=3068 脑子转个弯总算看懂马拉车算法了.记录一下思路和模板. 马拉车算法是在O(n)的时间内求出最大回文子串. 一 ...

  4. 马拉车——Manacher一篇看上去很靠谱的理解(代码显然易懂)

    由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以这里我们使用一个技巧,在字符间插入一个字符(前提这个字符未出现在串里).举个例子:s="a ...

  5. 一点总结-关于debug比赛

    上午的题目是: 1. main里面定义的变量必须手动初始化,使用memset或者其他,函数外或者函数内,会进行初始化为0. 2. 最长回文子串的马拉车manacher算法,不会写! 3. 数字三角形d ...

  6. ACM-ICPC 2018 南京网络赛

    题目顺序:A C E G I J L A. An Olympian Math Problem 打表,找规律,发现答案为n-1 C. GDY 题意: m张卡片,标号1-13: n个玩家,标号1-n:每个 ...

  7. ACM模板_axiomofchoice

    目录 语法 c++ java 动态规划 多重背包 最长不下降子序列 计算几何 向量(结构体) 平面集合基本操作 二维凸包 旋转卡壳 最大空矩形 | 扫描法 平面最近点对 | 分治 最小圆覆盖 | 随机 ...

  8. [菜b]Isaunoya 的一些学习笔记…[保持咕咕咕]

    fread/fwrite标记永久化 分块 树链剖分 莫比乌斯反演 斜率优化/单调队列 kruskal重构树 回滚莫队 可持久化线段树/trie树 Link-Cut-Tree dsu on tree F ...

  9. Manacher's Algorithm 马拉车算法

    这个马拉车算法Manacher‘s Algorithm是用来查找一个字符串的最长回文子串的线性方法,由一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性,这 ...

随机推荐

  1. python 基础之 模块

    Python 基础之模块 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 就是一个python文件中定义好了类和方法,实现了一些功能,可以被别的python文 ...

  2. Spring 应用之Spring JDBC实现

    jdbcTemplate类的入门 方式一 POM.XML <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:x ...

  3. ASP.NET Core 1.0: Deploy to IIS

    尽管ASP.NET最新的官方文档记录了如何Deploy to IIS,但是实际操作起来依旧磕磕绊绊.官方文档地址:https://docs.asp.net/en/latest/publishing/i ...

  4. Mybatis加入日志

    *在mybatis-config.xml核心配置文件中加入如下设置,在configration中标签中加入 <!--打印日志,方便看输出SQL --> <settings> & ...

  5. Nginx下HTTP强制重定向至HTTPS

    Nginx下HTTP强制重定向至HTTPS 对于nginx来说,配置http强制重定向至https有多种多样的写法.可以直接rewrite,也可以用301重定向.但是直接拷贝网上的配置往往会出现问题, ...

  6. 【2018寒假集训Day 8】【最小生成树】Prim和Kruskal算法模板

    Luogu最小生成树模板题 Prim 原理与dijkstra几乎相同,每次找最优的点,用这个点去松弛未连接的点,也就是用这个点去与未连接的点连接. #include<cstdio> #in ...

  7. python--数字灯管

    import turtle import time def drawLine(draw): #绘制单段数码管 turtle.pendown() if draw else turtle.penup() ...

  8. 10分钟学会Python函数基础知识

    看完本文大概需要8分钟,看完后,仔细看下代码,认真回一下,函数基本知识就OK了.最好还是把代码敲一下. 一.函数基础 简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运 ...

  9. Mac OS 终端利器 iTerm2(怕以后找不到,自存自用)

    之前一直使用 Mac OS 自带的终端,用起来虽然有些不太方便,但总体来说还是可以接受的,是有想换个终端的想法,然后今天偶然看到一个终端利器 iTerm2,发现真的很强大,也非常的好用,按照网上配置了 ...

  10. Django简介以及MVC模式

    一.简介 Django,是当前Python世界里最负盛名且成熟的网络框架.最初用来制作在线新闻的Web站点. Django是一个基于python的web重量级框架 重指的是为发开者考虑的多 采用了MV ...