马拉车,O(n)求回文串

对整个马拉车算法步骤做个总结:

  • 第一步:将每个原字母用两个特殊字符包围如:
aaa --> #a#a#a#
abab -->#a#b#a#b
同时可以由这个翻倍的字符串得到一个性质:
如果在此串中,以特殊字符,如'#'为回文中心,那么在原串中回文长度就是偶数,如果是以正常字符为回文中心,那么在原串中的回文长度就是奇数

这样可以使得所有的奇数长度的回文串变成偶数长度

  • 第二步:设置P数组P[N*3];代表S[i]的回文半径(包括自身),并设置id为迄今为止回文半径最大的字符位置,max为id+P[id],该回文串的右边界位置

  • 第三步:求p数组,这里存在一个结论:

    如果mx > i,那么P[i] >= min(P[2 * id - i], mx - i)。

    2id-i,将其转化到x坐标上看,正好是i关于id的对称点,可以这么理解:由于mx>i,可知i-->mx是在已知范围以内的,因为以i为回文中心的回文串是与以其关于对称点j=2id-i存在长度至少为mx-i相同回文半径的。

    如图:(x和y至少是同样长的,因为以j为中心的是回文串,同id同i,根据回文串性质可得)

  • 第四步:对于p数组的认识,p数组是在原字符串翻倍后的基础上进行运算的,很显然,若p[i]=6,那么原串的回文长度(不是回文半径)是5 :设原半径为ans,回文长度为len,那么len=ans2-1;而此时半径为x=ans2,转化可得len=x-1;

这里贴上两份模板

模板1:

void init()
{
len1=strlen(s);
str[0]='(';
str[1]='#';
for(int i=0;i<len1;i++)
{
str[i*2+2]=s[i];
str[i*2+3]='#';
}
len2=len1*2+2;
str[len2]=')';
}
void Manacher()
{
memset(p,0,sizeof(p));
int id=0,mx=0;
for(int i=1;i<len2;i++)
{
if(mx>i) p[i]=min(mx-i,p[2*id-i]);
else p[i]=1;
for(;str[i+p[i]]==str[i-p[i]];p[i]++);
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
}

模板2:

int Init(int n)
{
cpy[0]='(';cpy[1]='#';
for(int i=0,j=2;i<n;j+=2,i++)
{
cpy[j]=a[i];
cpy[j+1]='#';
}
n=n*2+3;
cpy[n-1]=')';
return n;
}
void Manacher(char *s,int n,int *p)
{
for(int i=1,j=0,k;i<n;i+=k)
{
while(s[i-j-1]==s[i+j+1]) j++;
p[i]=j;
for(k=1;k<=p[i]&&p[i-k]!=p[i]-k;k++)
{
p[i+k]=min(p[i-k],p[i]-k);
}
j=max(j-k,0);
}
}

马拉车,O(n)求回文串的更多相关文章

  1. Palindrome - URAL - 1297(求回文串)

    题目大意:RT   分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的.   线段数+后缀数组代码如下: ...

  2. 2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对)

    2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对) https://www.luogu.com.cn/problem/P5041 题意: 给一个字符串 \(S\) ,每 ...

  3. LOJ 2452 对称 Antisymmetry——用hash求回文串数

    概念 用hash求最长回文串/回文串数 首先,易知,回文串具有单调性. 如果字符串 $s[l...r]$ 为回文串串,那么 $s[x...y]$($l < x, y < r$ 且 $|l- ...

  4. manacher算法,求回文串

    用来求字符串最长回文串或者回文串的总数量 #include<map> #include<queue> #include<stack> #include<cma ...

  5. hdu 3294 manacher 求回文串

    感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...

  6. hihocoder 1032 manachar 求回文串O(n)

    #include <cstdio> #include <iostream> #include <algorithm> #include <queue> ...

  7. HDU 5371(2015多校7)-Hotaru&#39;s problem(Manacher算法求回文串)

    题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列.该子序列分为三部分,第一部分与第三部分同样,第一部分与第二部分对称.假设存在求最长的符合这样的条件的序列. ...

  8. 拓展KMP求回文串

    题目:hdu3613: 题意:有26字母对应的价值,然后给出以个串,把它分成两段字串,如果字串是回文串,串的价值就是每个字符和,不是就为0.求最大价值. 博客 分析:拓展KMP的应用求回文字串. #i ...

  9. 3676: [Apio2014]回文串 求回文串长度与出现次数的最大值

    「BZOJ3676」[Apio2014] 回文串   Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所 ...

随机推荐

  1. Excel设定编辑列权限的方法

    工具---保护--允许用户编辑区域 --新建-- 选择(或输入)引用单元格 ,区域密码:对不同的人不同的区域用不同的密码,设置完成后,保护工作表(密码用管理员的),即可

  2. 6章 Models

    传统的MVC结构中,有模型这么一个概念.Django中,Models又是怎么一回事呢? 刚才生成的这些乱七八糟的数据迁移就是Django自带的一些应用 INSTALLED_APPS = [ 'djan ...

  3. 常用的八大排序算法,含java实例(copy)

    说明:转载于http://www.cnblogs.com/qqzy168/archive/2013/08/03/3219201.html 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序( ...

  4. Linux 下編輯 PDF 檔的工具(PDF editor under Linux)(转载)

    转自:http://www.gtwang.org/2011/05/linux-pdf.html PDF 檔雖然是一個跨平台的檔案格式,但 Adobe 只有提供免費的 Adobe Reader,要看 P ...

  5. win7安装oracle

    1.下载 2.安装 主目录关键重要

  6. [App Store Connect帮助]六、测试 Beta 版本(1)TestFlight Beta 版测试概述(iOS、Apple TVOS、watchOS)

    TestFlight Beta 版测试让您可以分发您 App 的 Beta 版构建版本给测试员并收集反馈.您可以在您的 App Store Connect 帐户中一次为至多 100 个 App 启用 ...

  7. mysql之distinct

    记录一下这几天看mysql必知必会的小知识点: 关于mysql查询不同的行 比如记录表中 查询有多少个城市 可能查出很多城市 可以用distinct 来解决这个问题 SELECT DISTINCT c ...

  8. Classic BADI总结

    这里对sap Classic Badi 做一下总结,虽然已经是过时的技术了. Classic BADI的创建 Classic BADI的实施 Classic BADI的调用及运行原理 New BADI ...

  9. mycat登录报错Host 'XXX' is blocked because of many connection errors的另一种解决思路

    报错时机 使用了mycat,而不是单纯使用了mysql. 报错信息 ERROR 1129 (HY000): Host '1.23.22.18' is blocked because of many c ...

  10. laravel学习一

    Laravel 是一款简洁,优雅的一款框架,可以说是入门TP后的第二款可以选择的框架. 目录部分: app -> 自己写的代码 http -> Controller -> 控制器 b ...