Manacher模版
现在讲的也是一种处理字符串的方法,叫做Manacher,有点像“马拉车”
1179: [视频]【Manacher】最长回文子串
时间限制: 1 Sec 内存限制: 128 MB
提交: 209 解决: 120
[提交] [状态] [讨论版] [命题人:admin]题目描述
【题意】
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文子串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
【输入格式】
输入有多组数据,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
每组数据之间由空行隔开(该空行不用处理)
字符串长度len<=100000
【输出格式】
每一行一个整数x,对应一组数据,表示该组数据的字符串中所包含的最长回文子串长度.
【样例输入】
aaaaabab
【样例输出】
4 3
朴素做法:3重for循环:第一重枚举开头,第二重枚举结尾,第三重用来判断是不是回文串,记录答案更新最大值
但是我们的数据范围是10万,三重for循环是不可能不炸的
然后就要用到我们的Manacher,但是这道题也可以用后缀数组来做,不过Manacher更简单方便,下面我们来看一下“马拉车”
a w e r s e s s a
# a # w # c # r # s # e # s # s # a #
我们看到一个串,要判断他的串时,我们就要分他的长度是单数还是复数的情况,为什么呢?因为我们的回文是有两种情况的,单数和偶数的情况是不一样的
(非常不方便)
所以我们在头和尾,以及两个字符之间加一个#号,(其他的也可以,只要是字符串当中没有出现过的就可以)
那么经过这个操作之后,不过原来是偶数还是奇数,加上#号之后都会变成奇数,这样我们处理起来就会方便很多# a # w # c # r # s # e # s # s # a #
p[ ]= 1 2 1 2 1 2 1 2 1 2 1 4 1 2 3 2 1 2 1
首先#号是自己一个,所以是1
a是与# a #构成,所以是2,剩下的都是同样的道理
一直到e的出现,他是 # s # e # s # 所以是4,这样我们就知道了p数组的实现了p[i]表示以i为中心构成的最长回文字串的结尾与i的距离(结果要+1,因为算上了i)
然后我们看回e,是第12个字符,p[12]=4,然后他的这个回文串的长度是7,向右延伸4个,向左延伸4个,重复算了1个,所以就是4*2-1=7(包括#号)
然后因为答案是不算#号的,所以真正的是 (7-1)/2=3
因为# s # e # s #头尾都有#号,所以删掉一个之后,就是一个#号与一个数字搭配,这样就可以直接除以2算出字串的真正长度所以我们发现最长回文字串的长度就是
=(p[i]*2-1-1)/2
=(p[i]*2-2)/2
=p[i]-1 (一定要记住这个最后的变式,特别重要)
看了我前面博客的一定都知道,这是我目前在讲字符串专题的时候用到的图是最简单的了
然后我们看到图
首先字符串的长度是1~len
l,r表示之前计算的最长回文字串的开头和结尾,r代表结尾所到达的最大的地方,l代表开头
pos代表回文串的中心分类讨论 (有两种情况)
1.i<r
我们可以发现p[i]=p[j]
因为l~r是一个回文串,那么我们就可以直接得出p[i]=p[j],那么p[i]就可以直接继承了2.i>=r
这个时候就不能直接继承了,因为我们不知道i后面的p数组是怎样的,所以我们只能直接暴力求出p[i]
然后j这个位置我们可以p[i]=min(p[j],r-i)
因为有时候i所构成的最长回文字串是比r还要长的,那么这个时候我们就只能继承i~r这个长度,不能继承到后面,因为我们根本不知道绿色格子的长度是不是相等的,所以我们不能继承到后面
有因为i与j对称,所以直接p[j]就可以了然后j的话,我们可以用 pos-(i-pos)=pos*2-i
因为i到pos的距离等于j到pos的距离,因为i是以pos为中心和j对称,也就是j是i的对称点所以我们可以直接用pos*2-i=j来确定j的位置
然后Manacher讲到这里的时候,我们的这道题就已经解决的差不多了,剩下的就是看代码的实现
(注释版 因为这个相对于EXKMP要好理解很多,所以可以先试着自己打一遍,再看注释深刻理解)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
char s[],tt[];/*tt表示新字符串,s表示原字符串*/
int p[],ans;
void Manacher()
{
int len=strlen(s+);
for(int i=;i<=len;i++) tt[*i-]='#',tt[*i]=s[i];/*构造带#新字符串*/
len=len*+;/*新字符串的长度*/
tt[len]='#';/*最后面也是#号*/
int pos=,r=;
/*r为之前计算的最长回文字串的结尾所到达的最大地方(右端点的最大值)
pos表示r所在最长回文字串的中心*/
for(int i=;i<=len;i++)
{
int j=*pos-i;/*j为i的对称点*/
if(i<=r) p[i]=min(p[j],r-i);
/*
如果i<=R的话,分两种情况
第一种情况p[j]>R-i时,表示j对称点的最长回文子串已经越出R的界限了
这时,因为我们不确定大于R时的情况,所以p[i]暂时等于R-i
第二种情况p[j]<=R-i时,那就可以直接继承p[j]得p[i]=p[j]
综合以上两种情况,我们可以用p[i]=min(p[j],R-i)来归纳
*/
else p[i]=;/*不然就为1,就是自己成为一个回文串*/
while(<=i-p[i] && i+p[i]<=len && tt[i-p[i]]==tt[i+p[i]]) p[i]++;
/*i-p[i]就是i的前面几个位置>=1,而且i的右边几个位置<=len,也就是说我构成的p[i]长度的是不会不合法的,
如果i-p[i]的字符等于i+p[i]的话,也就是说我的回文是成立的,变长了,那么长度增加*/
if(i+p[i]>r)/*右端点比r大*/
{
pos=i;/*把pos定为i*/
r=i+p[i];/*更新r*/
}
}
ans=;
for(int i=;i<=len;i++) ans=max(ans,p[i]-);/*p[i]-1就是真正回文串的长度
那么有#号怎么办,有#号也没有关系,因为p[i]-1终究是没有#号的,其实这个我们直接推出来的过程,而且记录的是最大值,
所以的话,根本不会出现这种情况*/
/*
首先当前的最长回文子串长度为2*p[i]-1
因为我们得到的p数组是在加了#号后的字符串上操作的,所以我们要对答案进行处理
因为#号处于首尾和每个字符之间,所以我们就可以保证所得出的最长回文子串的首尾都为#
这时我们可以得出不带#号的回文串的长度为(2*p[i]-1-1)/2=p[i]-1
所以真正的最长回文子串就是p[i]-1
ans记录最长的回文子串长度
*/
}
int main()
{
while(scanf("%s",s+)!=EOF)
{
Manacher();
printf("%d\n",ans);
}
return ;
}
Tristan Code 注释版
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
char s[],tt[];
int p[],ans;
void Manacher()
{
int len=strlen(s+);
for(int i=;i<=len;i++) tt[*i-]='#',tt[*i]=s[i];
len=len*+;
tt[len]='#';
int pos=,r=;
for(int i=;i<=len;i++)
{
int j=*pos-i;
if(i<=r) p[i]=min(p[j],r-i);
else p[i]=;
while(<=i-p[i] && i+p[i]<=len && tt[i-p[i]]==tt[i+p[i]]) p[i]++;
if(i+p[i]>r)
{
pos=i;
r=i+p[i];
}
}
ans=;
for(int i=;i<=len;i++) ans=max(ans,p[i]-);
}
int main()
{
while(scanf("%s",s+)!=EOF)
{
Manacher();
printf("%d\n",ans);
}
return ;
}
Tristan Code 非注释版
Manacher模版的更多相关文章
- HDU 3294 Manacher模版题
点击打开链接 题意:求最长回文子串所在的区间,然后第一个字符代表a,以后的顺推,最后输出这个区间顺推后的串 思路:Manacher轻松水过.记录下最长回文串的位置和长度即可了,然后输出时自己处理一下, ...
- Ural 1297 Palindrome(Manacher或者后缀数组+RMQ-ST)
1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The “U.S. Robots” HQ has just received a ...
- P3805 【模版】manacher算法(manacher)
P3805 [模版]manacher算法 题目描述 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 字符串长度为n 输入输出格式 输入格式: 一行小写英文字符a ...
- P3805 【模版】manacher算法
题目描述 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 字符串长度为n 输入输出格式 输入格式: 一行小写英文字符a,b,c...y,z组成的字符串S 输出格 ...
- hdu_3068_最长回文(Manacher)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:给你一个字符串,让你求最长的回文子串. 题解:数据量比较大,暴力O(n2)会超时,直接上马 ...
- Manacher详解
之前的字符串题解中对Manacher的思想进行了简略的介绍,在这篇文章中,我将会详细的将这个算法的初衷和具体实现理论进行解释.声明一点,这是我个人的理解,可能有不全面之处,望多包涵.在之前的几篇文章中 ...
- Kuangbin 带你飞 KMP扩展KMP Manacher
首先是几份模版 KMP void kmp_pre(char x[],int m,int fail[]) { int i,j; j = fail[] = -; i = ; while (i < m ...
- 创建ABPboilerplate模版项目
本文是根据角落的白板报的<通过ABPboilerplate模版创建项目>一文的学习总结,感谢原文作者角落的白板报. 1 准备 开发环境: Visual Studio 2015 update ...
- 使用boilerplate模版创建解决方案
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 话不多说,让我们开始干吧!对于还没有接触ABP框架或者接触时间还不是很长的小伙伴来说,我建议还是使用官方建议的做法,那就是到ABP ...
随机推荐
- Spring——注解
一.IOC注解 1.用于向Spring容器中注入bean: @Component:向Spring容器中注入bean @Repository:用于标注Dao层 @Service:用于标注Service业 ...
- Complete Tripartite
D - Complete Tripartite 思路:这个题是个染色问题.理解题意就差不多写出来一半了.开始的时候还想用离散化来储存每个点的状态,即它连接的点有哪些,但很无奈,点太多了,long lo ...
- Django框架使用
---恢复内容开始--- Django 创建第一个项目 本章我们将介绍Django 管理工具及如何使用 Django 来创建项目,第一个项目我们以 HelloWorld 来命令项目. Django 管 ...
- RabbitMQ MQTT协议和AMQP协议
RabbitMQ MQTT协议和AMQP协议 1 序言... 1 1.1 RabbitMq结构... 1 1.2 RabbitMq消息接收... 4 1.3 Ex ...
- <% 拼写页面
js中 function udSelect(obj){ var val = $("#"+obj.id).val(); $("select[cd="+obj.id ...
- Git客户端执行命令报错: fatal: Authentication failed for'xxxxx.git',但是又不弹出窗口重新输入用户名和密码的解决办法
1.Git版本:Git-2.17.0 2.引起git报错的原因 在变更远程仓库路径的的时候,弹出过一个窗口输入用户名和密码,但是输错了,之后执行任何拉取和更新的命令都会报如下的错: fatal: Au ...
- 使用Jmeter对观影券查询接口做性能测试
线程数:虚拟用户数.一个虚拟用户占用一个进程或线程.设置多少虚拟用户数在这里也就是设置多少个线程数. 准备时长: 设置的虚拟用户数需要多长时间全部启动.如果线程数为20 ,准备时长为10 ,那么需要1 ...
- TCP主动打开 之 第一次握手-发送SYN
tcp客户端与服务器端建立连接需要经过三次握手过程,本文主要分析客户端主动打开中的第一次握手部分,即客户端发送syn段到服务器端: tcp_v4_connect为发起连接主流程,首先对必要参数进行检查 ...
- UFLDL(Unsupervised Feature Learning and Deep Learning)
UFLDL(Unsupervised Feature Learning and Deep Learning)Tutorial 是由 Stanford 大学的 Andrew Ng 教授及其团队编写的一套 ...
- 【免费电子书】这可能是全网最齐的程序员编程电子书PDF合集了!
[toc] 最近博主
