马拉车manacher
目的:线性查找一个串的最长回文子串
时间复杂度:O(n)
len[i]表示以i为中心的回文串的半径,mx即为当前计算回文串最右边字符的最大值,p是中心点mid,mx-i和2*p-1关于p对称
https://blog.csdn.net/csdn_kou/article/details/82917937
hdu3068,板子题,求最长回文长度。
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn=;
- int t,len[maxn*];
- char S[maxn*],T[maxn*],s[maxn*];
- int init(char *str)
- {
- int n=strlen(str);
- for(int i=,j=;i<=*n;j++,i+=)
- {
- s[i]='#';
- s[i+]=str[j];
- }
- s[]='$';
- s[*n+]='#';
- s[*n+]='@';
- s[*n+]='\n';
- return *n+;
- }
- void manacher(int n)
- {
- int mx=,p=;
- for(int i=;i<=n;i++)
- {
- if(mx>i)len[i]=min(mx-i,len[*p-i]);
- else len[i]=;
- while(s[i-len[i]]==s[i+len[i]])len[i]++;
- if(len[i]+i>mx)mx=len[i]+i,p=i;
- }
- }
- int main()
- {
- while(scanf("%s",S)!=EOF)
- {
- int Len=strlen(S),n=init(S);
- for(int i=;i<=n;i++)len[i]=;
- manacher(n);
- int ans=;
- for(int i=;i<=n;i++)
- {
- ans=max(ans,len[i]-);
- }
- printf("%d\n",ans);
- }
- return ;
- }
2019徐州G colorful string,求所有回文子串的value之和,一个串的value为串中字母种类,dfs预处理了第i位前一个a-z的位置,复杂度26*n。
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int maxn=3e5+;
- int t,len[maxn*];
- char S[maxn*],T[maxn*],s[maxn*];
- int init(char *str){
- int n=strlen(str);
- for(int i=,j=;i<=*n;j++,i+=){
- s[i]='#';
- s[i+]=str[j];
- }
- s[]='$';
- s[*n+]='#';
- s[*n+]='@';
- s[*n+]='\n';
- return *n+;
- }
- void manacher(int n)
- {
- int mx=,p=;
- for(int i=;i<=n;i++){
- if(mx>i) len[i]=min(mx-i,len[*p-i]);
- else len[i]=;
- while(s[i-len[i]]==s[i+len[i]]) len[i]++;
- if(len[i]+i>mx) mx=len[i]+i,p=i;
- }
- }
- int dp[maxn*][],place[];
- int main()
- {
- scanf("%s",S);
- int Len=strlen(S),n=init(S);
- for(int i=;i<=n;i++)len[i]=;
- manacher(n);
- ll ans=;
- int k=;
- for(int i=;i<;i++)place[i]=-;
- for(int i=;i<=n;i++)
- {
- if(i%==)place[S[k++]-'a']=i;
- for(int j=;j<;j++)dp[i][j]=place[j];
- }
- for(int i=;i<=n;i++)
- {
- for(int j=;j<;j++)
- {
- if(i-dp[i][j]<len[i])
- {
- ans+=1ll*(len[i]-(i-dp[i][j]))/;
- }
- }
- }
- printf("%lld\n",ans);
- return ;
- }
hdu3613,一个串割成两个串,如果是回文串则val为所有字母val之和,否则为零。
字母的val题目给出,求使总串的val最高的割法的val值。
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn=5e5+;
- int t,len[maxn<<];
- char S[maxn<<],T[maxn<<],s[maxn<<];
- int init(char *str)
- {
- int n=strlen(str);
- for(int i=,j=;i<=*n;j++,i+=)
- {
- s[i]='#';
- s[i+]=str[j];
- }
- s[]='$';
- s[*n+]='#';
- s[*n+]='@';
- s[*n+]='\n';
- return *n+;
- }
- void manacher(int n)
- {
- int mx=,p=;
- for(int i=;i<=n;i++)
- {
- if(mx>i)len[i]=min(mx-i,len[*p-i]);
- else len[i]=;
- while(s[i-len[i]]==s[i+len[i]])len[i]++;
- if(len[i]+i>mx)mx=len[i]+i,p=i;
- }
- }
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--)
- {
- int val[]={};
- for(int i=;i<;i++)scanf("%d",&val[i]);
- cin>>S;
- int Len=strlen(S),n=init(S);
- for(int i=;i<=n;i++)len[i]=;
- manacher(n);
- int lg=,rg=,ans=;
- for(int i=;i<Len;i++)rg+=val[S[i]-'a'];
- for(int i=;i<=n;i++)
- {
- if(i%==)
- {
- lg+=val[s[i]-'a'];
- rg-=val[s[i]-'a'];
- }
- else
- {
- int l=,r=*Len+,tmplg=,tmprg=;
- if(i!=l&&i!=r)
- {
- int mid1=(l+i)>>,mid2=(i+r)>>;
- if(len[mid1]==mid1-l+)tmplg=lg;
- if(len[mid2]==r-mid2+)tmprg=rg;
- ans=max(ans,tmplg+tmprg);
- }
- }
- }
- printf("%d\n",ans);
- }
- return ;
- }
hdu3294,求最早出现的最长回文串的l、r区间,并且转换后输出
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn=2e5+;
- int t,len[maxn<<];
- char S[maxn<<],T[maxn<<],s[maxn<<];
- int init(char *str)
- {
- int n=strlen(str);
- for(int i=,j=;i<=*n;j++,i+=)
- {
- s[i]='#';
- s[i+]=str[j];
- }
- s[]='$';
- s[*n+]='#';
- s[*n+]='@';
- s[*n+]='\n';
- return *n+;
- }
- void manacher(int n)
- {
- int mx=,p=;
- for(int i=;i<=n;i++)
- {
- if(mx>i)len[i]=min(mx-i,len[*p-i]);
- else len[i]=;
- while(s[i-len[i]]==s[i+len[i]])len[i]++;
- if(len[i]+i>mx)mx=len[i]+i,p=i;
- }
- }
- int main()
- {
- char ch;
- while(scanf("%c %s",&ch,S)!=EOF)
- {
- int Len=strlen(S),n=init(S);
- for(int i=;i<=n;i++)len[i]=;
- manacher(n);
- int ans=,l=,r=;
- for(int i=;i<=n;i++)
- {
- if(len[i]->ans)
- {
- ans=len[i]-;
- l=(i-len[i]+)/;
- r=(i+len[i]-)/;
- }
- }
- if(ans<)printf("No solution!\n");
- else
- {
- printf("%d %d\n",l,r);
- for(int i=l;i<=r;i++)
- {
- S[i]=S[i]-ch+'a';
- if(S[i]>'z')S[i]=S[i]-'z'+'a'-;
- if(S[i]<'a')S[i]=S[i]+'z'-'a'+;
- }
- S[r+]='\0';
- printf("%s\n",S+l);
- }
- getchar();
- }
- return ;
- }
hdu4513,最长递增(不降)回文串,manacher里只需要改个while
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn=1e5+;
- int t,len[maxn*];
- int s[maxn*],T[maxn*],S[maxn*];
- int init(int *str,int n)
- {
- for(int i=,j=;i<=*n;j++,i+=)
- {
- s[i]=-;
- s[i+]=str[j];
- }
- s[]=-;
- s[*n+]=-;
- s[*n+]=-;
- return *n+;
- }
- void manacher(int n)
- {
- int mx=,p=;
- for(int i=;i<=n;i++)
- {
- if(mx>i)len[i]=min(mx-i,len[*p-i]);
- else len[i]=;
- while(s[i-len[i]]==s[i+len[i]]&&s[i-len[i]]<=s[i-len[i]+])len[i]++;
- if(len[i]+i>mx)mx=len[i]+i,p=i;
- }
- }
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--)
- {
- int n;
- scanf("%d",&n);
- for(int i=;i<n;i++)
- scanf("%d",&S[i]);
- int Len=n,len2=init(S,n);
- for(int i=;i<=n;i++)len[i]=;
- manacher(len2);
- int ans=;
- for(int i=;i<=len2;i++)
- {
- ans=max(ans,len[i]-);
- }
- printf("%d\n",ans);
- }
- return ;
- }
...
马拉车manacher的更多相关文章
- 51nod 1595 回文度 | 马拉车Manacher DP
51nod 1595 回文度 题目描述 如果长度为n的字符串是一个回文串,同时它的长度为floor(n/2)的前缀和后缀是K-1度回文串,则这个字符串被称为K度回文串.根据定义,任何字符串(即使是空字 ...
- HDU - 3068 最长回文(马拉车Manacher)题解
思路:马拉车裸题,我们用一个p[i]数组代表以i为中心的最大回文半径.这里用了一个小技巧,如果一个串是aaaa这样的,那我们插入不相干的字符使它成为#a#a#a#a#,这样无论这个串是奇数还是偶数都会 ...
- hdu3068-最长回文-马拉车(Manacher)算法
http://acm.hdu.edu.cn/showproblem.php?pid=3068 脑子转个弯总算看懂马拉车算法了.记录一下思路和模板. 马拉车算法是在O(n)的时间内求出最大回文子串. 一 ...
- 马拉车——Manacher一篇看上去很靠谱的理解(代码显然易懂)
由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以这里我们使用一个技巧,在字符间插入一个字符(前提这个字符未出现在串里).举个例子:s="a ...
- 一点总结-关于debug比赛
上午的题目是: 1. main里面定义的变量必须手动初始化,使用memset或者其他,函数外或者函数内,会进行初始化为0. 2. 最长回文子串的马拉车manacher算法,不会写! 3. 数字三角形d ...
- 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:每个 ...
- ACM模板_axiomofchoice
目录 语法 c++ java 动态规划 多重背包 最长不下降子序列 计算几何 向量(结构体) 平面集合基本操作 二维凸包 旋转卡壳 最大空矩形 | 扫描法 平面最近点对 | 分治 最小圆覆盖 | 随机 ...
- [菜b]Isaunoya 的一些学习笔记…[保持咕咕咕]
fread/fwrite标记永久化 分块 树链剖分 莫比乌斯反演 斜率优化/单调队列 kruskal重构树 回滚莫队 可持久化线段树/trie树 Link-Cut-Tree dsu on tree F ...
- Manacher's Algorithm 马拉车算法
这个马拉车算法Manacher‘s Algorithm是用来查找一个字符串的最长回文子串的线性方法,由一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性,这 ...
随机推荐
- python 基础之 模块
Python 基础之模块 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 就是一个python文件中定义好了类和方法,实现了一些功能,可以被别的python文 ...
- Spring 应用之Spring JDBC实现
jdbcTemplate类的入门 方式一 POM.XML <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:x ...
- ASP.NET Core 1.0: Deploy to IIS
尽管ASP.NET最新的官方文档记录了如何Deploy to IIS,但是实际操作起来依旧磕磕绊绊.官方文档地址:https://docs.asp.net/en/latest/publishing/i ...
- Mybatis加入日志
*在mybatis-config.xml核心配置文件中加入如下设置,在configration中标签中加入 <!--打印日志,方便看输出SQL --> <settings> & ...
- Nginx下HTTP强制重定向至HTTPS
Nginx下HTTP强制重定向至HTTPS 对于nginx来说,配置http强制重定向至https有多种多样的写法.可以直接rewrite,也可以用301重定向.但是直接拷贝网上的配置往往会出现问题, ...
- 【2018寒假集训Day 8】【最小生成树】Prim和Kruskal算法模板
Luogu最小生成树模板题 Prim 原理与dijkstra几乎相同,每次找最优的点,用这个点去松弛未连接的点,也就是用这个点去与未连接的点连接. #include<cstdio> #in ...
- python--数字灯管
import turtle import time def drawLine(draw): #绘制单段数码管 turtle.pendown() if draw else turtle.penup() ...
- 10分钟学会Python函数基础知识
看完本文大概需要8分钟,看完后,仔细看下代码,认真回一下,函数基本知识就OK了.最好还是把代码敲一下. 一.函数基础 简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运 ...
- Mac OS 终端利器 iTerm2(怕以后找不到,自存自用)
之前一直使用 Mac OS 自带的终端,用起来虽然有些不太方便,但总体来说还是可以接受的,是有想换个终端的想法,然后今天偶然看到一个终端利器 iTerm2,发现真的很强大,也非常的好用,按照网上配置了 ...
- Django简介以及MVC模式
一.简介 Django,是当前Python世界里最负盛名且成熟的网络框架.最初用来制作在线新闻的Web站点. Django是一个基于python的web重量级框架 重指的是为发开者考虑的多 采用了MV ...