博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
51Nod1089最长回文子串 V2(Manacher算法)
阅读量:6580 次
发布时间:2019-06-24

本文共 1037 字,大约阅读时间需要 3 分钟。

俗称马拉车算法→_→

 

处理最长回文字串复杂度O(n)

 

这里菜鸡不会证,简单说一下思路。

 

由于回文串有奇有偶,所以将串之间和两边加上'#',为了防止后面某个地方超边界,新串0位置加上$。这样每个回文子串为#a#b#a#形式,必定奇数个,且原子串长度为新字串半径减一,求这个半径p[i]。(即p[i]是以i为中心的最长回文字串的半径)

 

i从1到n,过程中维护一个id点(id<i,i拉着id走,马拉车),它是某个回文子串的中心,这个字串右边界是当前最大的。(p[i]是半径,故i+p[i]为边界)

 

那么当右边界比i还大时,就可以根据对称性,找到i关于id的对称点j=2*id-i,来优化找字串的过程。怎么优化呢?在id管辖范围内,p[i]和p[j]情况是相同的。由于超出id右边界的的地方不符合对称性,因此p[i]=p[j]当且仅当p[j]小于等于j-(id-p[id])(即j串的左边界不超出id串的左边界),否则只能直接到id右边界,p[i]=mx-i,之后的手动算。

 

如果id右边界太小,不能做优化,也得手动算。

 

以下代码:

1 #include
2 #include
3 #include
4 #include
5 #define ll long long 6 using namespace std; 7 char s[100020],sn[200020]; 8 int p[200020]; 9 int init(){10 int len=strlen(s);11 sn[0]='$';sn[1]='#';12 int j=2;13 for(int i=0;i
mx){32 id=i;33 mx=p[i]+i;34 }35 mx_len=max(mx_len,p[i]-1);36 }37 return mx_len;38 }39 int main(){40 cin>>s;41 cout<

 

转载于:https://www.cnblogs.com/sz-wcc/p/10445994.html

你可能感兴趣的文章
iOS socket通信,编解码,浮点型数据解析
查看>>
手把手教你如何新建scrapy爬虫框架的第一个项目(下)
查看>>
前端基础15:JS作用域基础
查看>>
Linux系统相关命令
查看>>
BATJ面试必会之 Spring 篇(一)
查看>>
表驱动法
查看>>
什么是企业内训
查看>>
firefox无法显示java插件plugin
查看>>
H3C设备之OSPF DR选举
查看>>
List grantee right in oracle
查看>>
Activity生命周期
查看>>
通过VBS编写自动输入账号和密码、自动登录程序的脚本
查看>>
MTK APSoC SDK MT7621编译固件的快速开始
查看>>
深度解析Istio系列之安全模块篇
查看>>
Linux 系统 审计
查看>>
JS -------------------设置弹出框位置屏幕的中间
查看>>
性能测试 vbs使用(一)
查看>>
1.2 linux哲学思想
查看>>
jQuery基础
查看>>
BZOJ5312:冒险——题解
查看>>