题目链接

manacher算法:在线性时间内求一个字符串中所有/最长回文串的算法。

先来考虑一下暴力的算法,枚举每个中点,向两边扩展,时间复杂度\(O(n^2)\)。

来分析下此算法的缺点。

1、因为回文串有奇偶之分,所以要分类讨论,\(abba\)的对称轴不在字符上,分类讨论就会有点麻烦。

为此,\(manacher\)算法的解决方案是在每个字符之间插入一个相同的字符,比如说\(\#\),

\(ababa->\#a\#b\#a\#b\#a\#\),这样就不用考虑回文串的奇偶性了。

2、效率低。为什么低?每个位置会被重复遍历。和\(KMP\)算法类似,\(manacher\)也是利用已有信息减少重复无用操作。

比如说\(abacaba\),这是一个回文串,但两边的\(aba\)也都是一个回文串,我们在枚举到右边的\(b\)时就已经能确定已这个\(b\)为中心的回文串的回文半径至少为\(2\),然后直接从这个长度开始拓展就好了。设\(hw[i]\)表示以\(a[i]\)为回文中心的回文半径长度,\(maxright\)表示当前已发现的右端点最右的右端点,\(mid\)表示这个回文串的中心。

则有如下算法(我觉得看代码比看讲解容易懂些)

for(int i = 1; i < len; ++i){
if(i < maxright)
hw[i] = min(hw[(mid << 1) - i], hw[mid] + mid - i); //min左边的参数是这个点的对称点的hw值,右边的是保证这个部分在这个大回文串之内
else hw[i] = 1;
while(a[i + hw[i]] == a[i - hw[i]]) ++hw[i]; //拓展
if(hw[i] + i > maxright){ //更新右端点
maxright = hw[i] + i;
mid = i;
}
}

该题完整代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 11000010;
char b[MAXN], a[MAXN << 1];
int hw[MAXN << 1], ans, n;
int main(){
scanf("%s", b);
a[0] = a[1] = '#';
int len = strlen(b);
for(int i = 0; i < len; ++i)
a[(i << 1) + 2] = b[i], a[(i << 1) + 3] = '#';
int maxright = 0, mid; len = (len << 1) + 3;
for(int i = 1; i < len; ++i){
if(i < maxright)
hw[i] = min(hw[(mid << 1) - i], hw[mid] + mid - i);
else hw[i] = 1;
while(a[i + hw[i]] == a[i - hw[i]]) ++hw[i];
if(hw[i] + i > maxright){
maxright = hw[i] + i;
mid = i;
}
ans = max(ans, hw[i] - 1);
}
printf("%d\n", ans);
return 0;
}

【洛谷 P3805】 【模板】manacher算法的更多相关文章

  1. 洛谷P3805 [模板]Manacher算法 [manacher]

    题目传送门 题目描述 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 字符串长度为n 输入输出格式 输入格式: 一行小写英文字符a,b,c...y,z组成的字符 ...

  2. 洛谷.3805.[模板]manacher算法

    题目链接 之前做很早了没写这篇,补上. 记录当前ex[]最大的回文中心id和最远延伸范围mx! 关于串的构造: 应该是 @ #A#B#C#B#A# $ ,而不是 @ A#B#C#B#A $ 比如 @a ...

  3. 洛谷 P3805 【模板】manacher算法

    洛谷 P3805 [模板]manacher算法 洛谷传送门 题目描述 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 字符串长度为n 输入格式 一行小写英文字符 ...

  4. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  5. 洛谷 P3805【模板】manacher算法

    题目链接:https://www.luogu.com.cn/problem/P3805 Manacher算法$O(n)$: 求以每个字符为中心的最长回文串的半径:如果要求可以以字符间隙为回文中心,就要 ...

  6. [洛谷P3805]【模板】manacher算法

    题目大意:给你一个字符串,求出它的最长回文字段 题解:$manacher$算法 卡点:$p$数组未开两倍空间 C++ Code: #include <cstdio> #include &l ...

  7. 洛谷P3375 [模板]KMP字符串匹配

    To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...

  8. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  9. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

随机推荐

  1. performance_schema实现套路

      实现中大量使用多层次嵌套预编译,大量if else,wrapper等 不建议去看这个实现 start_mutex_wait_v1 if (flag_thread_instrumentation) ...

  2. Java检测端口的占用情况

    突然间想到这个问题,在网上搜了一下 http://blog.csdn.net/danieluk/article/details/18518175 网上有很多文章都是用上面那个方法来解决这个问题的,总感 ...

  3. 利用devcon工具编写bat脚本一键控制系统设备,如开启关闭网卡

    系统WIN7 x64位 下载devcon命令行工具 Download the "Windows Driver Kit (WDK) 7.1.0 from Microsoft: http://w ...

  4. java设计模式之装饰器模式以及在java中作用

    在JAVA I/O类库里有很多不同的功能组合情况,这些不同的功能组合都是使用装饰器模式实现的,下面以FilterInputStream为例介绍装饰器模式的使用  FilterInputStream和F ...

  5. User Agent的学习

    什么是User-Agent? User-Agent是一个特殊字符串头,被广泛用来标示浏览器客户端的信息,使得服务器能识别客户机使用的操作系统和版本,CPU类型,浏览器及版本,浏览器的渲染引擎,浏览器语 ...

  6. 团队作业4——第一次项目冲刺(Alpha版本)-第二篇

    项目冲刺——第二阶段 度过了敏捷冲刺,各个成员积极汇报各自的工作.好了,着手下一步规划! Mission 团队成员 任务 郭达  实现PHP后台的答题判分查看正确率 刘德培  编写博客 石浩洋  实现 ...

  7. LaTex标准article文件框架解析

    新建一个LaTex-Article文件 生成的文件框架代码 % ---------------------------------------------------------------- % A ...

  8. HDU 1445 Ride to School

    http://acm.hdu.edu.cn/showproblem.php?pid=1445 Problem Description Many graduate students of Peking ...

  9. 【SSH】——使用ModelDriven的利与弊

    在以往的web开发中,如果要在表单显示什么内容,我们就需要在Action中提前定义好表单显示的所有属性,以及一系列的get和set方法.如果实体类的属性非常多,那么Action中也要定义相同的属性.在 ...

  10. SQL 视图 局部变量 全局变量 条件语句 事务 触发器

    一.视图 1.视图是一张虚拟表,他所存储的不是实际数据,而是查询语句,但我们可以对视图进行像数据表一样的操作. 2.为什么使用视图呢?我的理解是:1.在远程传输数据时,可以避免过长的查询字符,减少流量 ...