Manacher模板 Poj3974
来源:互联网 发布:中国人民大学数据库 编辑:程序博客网 时间:2024/05/01 23:31
最长回文子串O(n)_Manacher算法
那么以某个字符为中心的前缀和后缀都是相同的,例如以一段回文串“aba”为例,以b为中心,它的前缀和后缀都是相同的,都是a
(红书里面有模板~但..好像是错的…)
Manacher算法
首先通过在每个字符的两边都插入一个特殊的符号,将所有可能的奇数或偶数长度的回文子串都转换成了奇数长度。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。
为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如$#a#b#a#。
以字符串12212321为例,插入#和
这两个特殊符号,变成了这两个特殊符号,变成了S[]=" #1#2#2#1#2#3#2#1#”,然后用一个数组 P[i] 来记录以字符S[i]为中心的最长回文子串向左或向右扩张的长度(包括S[i])。比如S和P的对应关系:
- S # 1 # 2 # 2 # 1 # 2 # 3 # 2 # 1 #
- P 1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1
Manacher算法增加两个辅助变量id和mx,
- 其中id表示最大回文子串中心的位置,
- mx则为id+P[id],也就是最大回文子串的边界。
- 如果mx > i,那么P[i] >= Min(P[2 * id - i], mx - i)这里的证明参考资料2
模板题 poj3974
#include <cstdio>#include <cstring>#define min(a,b) ((a<b)?a:b)#define max(a,b) ((a>b)?a:b)const int maxn = 2000000 + 200;char s[maxn];int p[maxn],len;void preprocess(){ memset(p, 0, sizeof(p)); len = (int)strlen(s); int i = len - 1,j = len << 1; s[j + 2] = '\0'; s[j + 1] = '#'; for (; i >= 0; i--) { s[j--] = s[i]; s[j--] = '#'; } s[0] = '@';//模拟新字符串的形成}int manacher(){ preprocess(); len = (int)strlen(s);//这里用 len = (len << 1) | 1会快很多 int maxLen = 0,right = 0,cen = 0; for (int i = 1; i <= len;i++) { p[i] = i < right ? min(p[(cen<<1)-i], right - i) : 1; //如果mx > i,那么P[i] >= Min(P[2 * id - i], mx - i) while (s[i-p[i]] == s[i+p[i]]) p[i]++;//原来统计区域外的部分 if (right < i + p [i]) { cen = i,right = i + p[i]; }//更新最右边 maxLen = max(maxLen, p[i]); } return maxLen - 1;}
大段参考资料
github_知乎
参考资料(英文参考资料里面推荐的”懂中文人,去看的最棒解释”)
0 0
- Manacher模板 Poj3974
- poj3974 manacher模板
- poj3974:Palindrome(manacher模板)
- 【POJ3974】Palindrome Manacher、模板题 裸题
- poj3974之manacher算法
- poj3974(Manacher算法)
- POJ3974 Palindrome (manacher算法)
- 【POJ3974】【Palindrome】【Manacher裸题】
- POJ3974 Palindrome(Manacher)
- poj3974(manacher)
- poj3974 Palindrome(manacher)
- [学习][poj3974]manacher Palindrome
- poj3974 Palindrome(manacher)
- poj3974 Palindrome,回文串,Manacher
- Manacher-模版题poj3974 hdu3068
- POJ3974 Palindrome(Manacher算法)
- Palindrome(poj3974)(manacher算法)
- Poj3974 最长回文子串 Manacher算法
- 背景建模--W4方法
- 算法导论第九章-中位数和顺序统计量-Cpp代码实现
- Install Fedora
- Linux之Ganglia源码安装
- 自定义图片形状
- Manacher模板 Poj3974
- Ganglia安装
- 深入理解C++中public、protected及private用法
- Android颜色分解与添加透明度
- 仿照映客的直播界面的刷礼物效果
- Jenkins + Github持续集成构建Docker容器
- 第十五周实践项目1-程序填空
- HDU5585 Numbers
- React基础