模板

【模板】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;
}

【P1659】[国家集训队]拉拉队排练

先求\(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算法笔记的更多相关文章

  1. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  2. 学习笔记 - Manacher算法

    Manacher算法 - 学习笔记 是从最近Codeforces的一场比赛了解到这个算法的~ 非常新奇,毕竟是第一次听说 \(O(n)\) 的回文串算法 我在 vjudge 上开了一个[练习],有兴趣 ...

  3. 「Manacher算法」学习笔记

    觉得这篇文章写得特别劲,插图非常便于理解. 目的:求字符串中的最长回文子串. 算法思想 考虑维护一个数组$r[i]$代表回文半径.回文半径的定义为:对于一个以$i$为回文中心的奇数回文子串,设其为闭区 ...

  4. Manacher算法学习笔记

    前言 Manacher(也叫马拉车)是一种用于在线性时间内找出字符串中最长回文子串的算法 算法 一般的查找回文串的算法是枚举中心,然后往两侧拓展,看最多拓展出多远.最坏情况下$O(n^2)$ 然而Ma ...

  5. 【学习笔记】Manacher算法

    本文部分图片来源 代码来源(代码是学姐哒.. 一.引入 Manacher算法是用来求最长回文子串的算法,时间复杂度O(n). 回文子串指的是''aacaa'',''noon'',这种正着反着读都一样的 ...

  6. Manacher 算法学习笔记

    算法用处: 解决最长回文子串的问题(朴素型). 算法复杂度 我们不妨先看看其他暴力解法的复杂度: \(O(n^3)\) 枚举子串的左右边界,然后再暴力判断是否回文,对答案取 \(max\) . \(O ...

  7. Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

    Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...

  8. 使用manacher算法解决最长回文子串问题

    要解决的问题 求一个字符串最长回文子串是什么.且时间复杂度 O(N) 具体描述可参考: LeetCode_5_最长回文子串 LintCode_200_最长回文子串 暴力解法 以每个字符为中心向左右两边 ...

  9. HDU3068 回文串 Manacher算法

    好久没有刷题了,虽然参加过ACM,但是始终没有融会贯通,没有学个彻底.我干啥都是半吊子,一瓶子不满半瓶子晃荡. 就连简单的Manacher算法我也没有刷过,常常为岁月蹉跎而感到后悔. 问题描述 给定一 ...

随机推荐

  1. useEffect传入第二个参数陷入死循环

    最近新项目刚上手,就用了react的hooks,之前也看过hooks的不少文章,只是还没实战实战. 业务场景1:需要在页面一开始时得到一个接口的返回值,取调用另一个接口. 我的思路是,先设置这个接口的 ...

  2. Ceph更换OSD磁盘

    目录 简介 更换OSD操作步骤 1. 故障磁盘定位 2. 摘除故障磁盘 3. 重建raid0 4. 重建osd 控制数据恢复及回填速度 简介 首先需要说明的是,ceph的osd是不建议做成raid10 ...

  3. [转帖]Linux监测某一时刻对外的IP连接情况

    Linux监测某一时刻对外的IP连接情况 https://blog.csdn.net/twt326/article/details/81454171 公司机器有病毒 需要分析一下. 之前有需要,在CS ...

  4. Redis(四)Pub/Sub

    发布与订阅 Pub/Sub模式应该非常熟悉,在现实应用中被广泛的使用.如:微博中关注某个号,这个号有发新博时,关注的都会收到:github上watch了某个项目,当有issue时,就会发邮件. Red ...

  5. WPF 精修篇 BackgroundWorker

    原文:WPF 精修篇 BackgroundWorker 效果 <Grid> <Grid.RowDefinitions> <RowDefinition Height=&qu ...

  6. 11、VUE混合

    1.混合的概念(mixture) 混合是以一种灵活的方式,为组件提供代码复用功能.(类似于封装) 混合对象可以包含任意的组件选项.当组件使用了混合对象时,混合对象的所有选项将被“混入”组件自己的选项中 ...

  7. android版本对应表

    API Level 最初Android版本 Linux内核版本 首次发布日期 后续Android版本 28 9 Unknown 2018-07-02(Beta 3) - 27 8.1 4.10 201 ...

  8. kubernetes学习之service、deployment、pod的关系

    deployment根据Pod的标签关联到Pod,是为了管理pod的生命周期 service根据Pod的标签关联到pod,是为了让外部访问到pod,给pod做负载均衡 需要注意: deployment ...

  9. 160--Intersection Of Two Linked List

    public class IntersectionOfTwoLinkedList { /* 解法一:暴力遍历求交点. 时间复杂度:O(m*n) 空间复杂度:O(1) */ public ListNod ...

  10. java基本类型的长度

    bit:位,一个二进制数据(0或者1),是1bit byte:字节,存储空间的基本单位,1byte=8bit 一个英文占一个字节,1字母=1byte=8bit 一个中文占两个字节,1汉字=2byte= ...