manacher算法笔记
模板
不妨先只考虑如何求长度为奇数的回文串
记\(P[i]\)表示以\(i\)为中心最多向两边扩展几个字符,满足回文
如串\(ababa\),
\(P[1]=0,P[2]=1,P[3]=3,P[4]=1,P[5]=0\)
如果暴力求解的话就是枚举每个中心位置,暴力判断能否扩展,在随机条件下跑不满,但是如\(aaaaaaa\)这样的串能卡到\(O(n^2)\)
\(manacher\)算法
尝试利用以前求得的信息
还是一位一位的枚举,枚举到位置\(i\),记\(maxr\)为以\(i\)前面的字符为中心的回文串中最大的右端点位置,\(k\)为它的中心位置
如果\(i<maxr\),\(i\)在这个回文串上 ,就可以知道i的字符与\(k-(i-k)\)相同,P[k-(i-k)]至少为min(maxr-i,P[k-(i-k)]


然后在暴力扩展就好了
复杂度:\(maxr\)最多移动\(n\)次,复杂度\(O(n)\)
偶回文串:
把原字符串的每一位中间加一个特殊字符'#',以'#'为中心的奇回文串就对应原串中的偶回文串
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN=22222222;
int n,p[MAXN];
char a[MAXN],s[MAXN];
int main()
{
scanf("%s",a+1);
n=strlen(a+1);
s[0]='$';
for(int i=1;i<=n;++i)
s[i*2-1]='$',s[i*2]=a[i];
s[n*2+1]='$';
n=n*2+1;
int mx=0,k=0,Ans=0;
for(int i=1;i<=n;++i){
if(i<=mx)
p[i]=min(mx-i,p[k*2-i]);
while(s[i+p[i]+1]==s[i-p[i]-1]) ++p[i];
if(i+p[i]>mx) k=i,mx=i+p[i];
Ans=max(Ans,p[i]);
}
printf("%d\n",Ans);
return 0;
}
先求\(P\)数组,每个\(P[i]\)代表着长度为1~2*P[i]+1的回文串,区间加一可用差分维护,最后算一下前\(k\)大就行了
#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
using namespace std;
const int MAXN=1000010;
const int MOD=19930726;
inline int qpow(int x,int k){
int s=1;
while(k){
if(k&1) s=s*x%MOD;
k>>=1;
x=x*x%MOD;
}
return s;
}
int n,k;
char s[MAXN];
int p[MAXN],diff[MAXN],a[MAXN];
signed main()
{
scanf("%lld%lld%s",&n,&k,s+1);
int mr=0,md=0;
s[0]='$';
for(int i=1;i<=n;++i){
if(i<=mr) p[i]=min(mr-i,p[md*2-i]);
while(s[i+p[i]+1]==s[i-p[i]-1]) ++p[i];
if(i+p[i]>mr) mr=i+p[i],md=i;
}
for(int i=1;i<=n;++i)
++diff[0],--diff[p[i]+1];
a[0]=diff[0];
for(int i=1;i<=n/2;++i)
a[i]=a[i-1]+diff[i];
int sum=0,Ans=1;
for(int i=n/2;i>=0;--i){
sum+=a[i];
if(sum>=k){
Ans=Ans*qpow(i*2+1,k-(sum-a[i]))%MOD;
break;
}
Ans=Ans*qpow(i*2+1,a[i])%MOD;
}
if(sum<k)
puts("-1");
else printf("%lld\n",Ans);
return 0;
}
manacher算法笔记的更多相关文章
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- 学习笔记 - Manacher算法
Manacher算法 - 学习笔记 是从最近Codeforces的一场比赛了解到这个算法的~ 非常新奇,毕竟是第一次听说 \(O(n)\) 的回文串算法 我在 vjudge 上开了一个[练习],有兴趣 ...
- 「Manacher算法」学习笔记
觉得这篇文章写得特别劲,插图非常便于理解. 目的:求字符串中的最长回文子串. 算法思想 考虑维护一个数组$r[i]$代表回文半径.回文半径的定义为:对于一个以$i$为回文中心的奇数回文子串,设其为闭区 ...
- Manacher算法学习笔记
前言 Manacher(也叫马拉车)是一种用于在线性时间内找出字符串中最长回文子串的算法 算法 一般的查找回文串的算法是枚举中心,然后往两侧拓展,看最多拓展出多远.最坏情况下$O(n^2)$ 然而Ma ...
- 【学习笔记】Manacher算法
本文部分图片来源 代码来源(代码是学姐哒.. 一.引入 Manacher算法是用来求最长回文子串的算法,时间复杂度O(n). 回文子串指的是''aacaa'',''noon'',这种正着反着读都一样的 ...
- Manacher 算法学习笔记
算法用处: 解决最长回文子串的问题(朴素型). 算法复杂度 我们不妨先看看其他暴力解法的复杂度: \(O(n^3)\) 枚举子串的左右边界,然后再暴力判断是否回文,对答案取 \(max\) . \(O ...
- Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)
Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...
- 使用manacher算法解决最长回文子串问题
要解决的问题 求一个字符串最长回文子串是什么.且时间复杂度 O(N) 具体描述可参考: LeetCode_5_最长回文子串 LintCode_200_最长回文子串 暴力解法 以每个字符为中心向左右两边 ...
- HDU3068 回文串 Manacher算法
好久没有刷题了,虽然参加过ACM,但是始终没有融会贯通,没有学个彻底.我干啥都是半吊子,一瓶子不满半瓶子晃荡. 就连简单的Manacher算法我也没有刷过,常常为岁月蹉跎而感到后悔. 问题描述 给定一 ...
随机推荐
- SpringBoot整合SpringDataJPA及在页面yaml中显示
SpringBoot整合SpringDataJPA及在页面yaml中显示 1:创建对应的数据表 2:添加依赖 3:配置数据源 1:创建对应的数据表 CREATE TABLE `user` ( `id` ...
- js 实现 promise
本文仅用于个人技术记录,如误导他人,概不负责. 本文有参考其他文章,不过地址忘了~~~. ======================================================= ...
- 024 如何让html引用公共的头部和尾部(多个html文件公用一个header.html和footer.html)
前端静态html页面,封装公共的头文件(header:顶部页眉,顶部导航栏等部分)和尾部文件(footer:CopyRight.友情链接等部分) 当前方法:通过load()函数,引入公共头部和尾部文件 ...
- Java for循环每次都通过list.size()和 string.length()获取大小是否消耗性能?
前言 有人说在for循环之前用一个局部变量先获取到list.size().str.length(),然后在for循环的判断条件里通过这个局部变量替换list.size().str.length()会节 ...
- Base64和本地以及在线图片互转
package com.ruoyi.common.utils; import java.io.ByteArrayOutputStream; import java.io.FileInputStream ...
- 反弹Shell原理及检测技术研究
1. 反弹Shell的概念本质 所谓的反弹shell(reverse shell),就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端. 本文会先分别讨论: ...
- thinkphp3.2.3集成phpexcel1.8导出设置单元格合并
1 到这里下载classes里面的文件 https://github.com/PHPOffice/PHPExcel 2 然后放到 thinkphp的vendor 新建一个文件夹 Phpexcel 然 ...
- 虚拟机Ubuntu18.04 root下 连接 windows 中 winScp
先查看自己虚拟机中是否有 ssh服务 如果没有的话先安装 apt-get install openssh-server 安装完之后 先手动开启一下服务 /etc/init.d/ssh restart ...
- wcf序列化嵌套类(如TreeNode)异常原因
循环引用类在WCF中的传递 循环引用类在WCF中的传递问题,例如: [DataContract] public class AB { public string name { ...
- 网络编程——TCP协议、UDP协议、socket套接字、粘包问题以及解决方法
网络编程--TCP协议.UDP协议.socket套接字.粘包问题以及解决方法 TCP协议(流式协议) 当应用程序想通过TCP协议实现远程通信时,彼此之间必须先建立双向通信通道,基于该双向通道实现数 ...