跟风Manacher算法整理
这是上上周天机房一位神仙讲的,\(gu\)了这么久才来整理\(w\),神仙讲的基本思路已经全都忘记了,幸好的是神仙写了\(blog\),吹爆原博浅谈\(Manacher\)算法,以及原博神仙\(ych\)!
再吹一波\(ych\):
太巨了!
\(Manacher\)是一种\(O(n)\)求回文字符子串的算法。(然后迷惑的记得当时问神仙\(ych\)一个sha diao问题:子串是连续的嘛?显然这里的回文子串是连续的;
\(Solution:\)
对于一串字符串,对于其中的每一个字符我们都维护一个\(R[i]\)表示这个字符串的最长回文半径,但是这个时候出现了\(bug\):
\(ykyyky\)
\(ykykyky\)
对于前一个子串,是偶数回文子串,而后一个回文子串是奇数回文子串。这个时候我们该怎么表示它们回文半径的差别?\(3\)和\(3.5\)?✘ 这个时候我们可以在每个字符串之间加‘\(\#’\)
\(\#y\#k\#y\#y\#k\#y\#\)
\(\#y\#k\#y\#k\#y\#k\#y\#\)
于是这样它们的回文半径就唯一确定了;
看处理:\(R[i]\)表示最长回文半径,当我们求得每个位置的\(R[i]\),当加了\('\#'\)之后,\(R[i]_{max}-1\)就是我们要求的最长回文串长度(感性 举例李姐
怎么处理?
求\(R[i]\)
设前\(i-1\)个数中的回文串的右端点的最大值为\(r\),取得最大右端点的数为\(mid\)。显然\(r=mid+R[mid]\)
\(\mathfrak{A}.\)\(i\leq r\)
计算\(i\)关于\(mid\)的对称点\(j=mid*2-i\),
\(\mathfrak{a}.\)\(j-R[j]>mid-R[mid]\),即\(i\)的对称点的回文串的范围包含在\(mid\)对应点的回文串范围,那么\(i\)的回文串和\(j\)的回文串一定是对称分布的(因为\(i、j\)关于\(mid\)对称并且在\(mid\)的回文半径内),则\(R[i]=R[j]\)
\(\mathfrak{b}.\) \(j-R[j]\leq mid-R[mid]\),则此时关于\(i、j\)关于\(mid\)对称分布并且在\(mid\)回文半径内的一定是对称的,但是在回文半径之外是否对称我们不清楚,因此我们用最简单粗暴的办法:暴力拓展;
\(\mathfrak{B}.i>r\)
于是暴力拓展√
在每次完成以上三项后,尝试更新\(r、mid\):
if(r<i+R[i]) {
r=i+R[i]-1;
mid=i;
}
然后复杂度不会证,(一定是我太菜了.
\(Code:\)
码量不是很大,注意字符串头尾都要插入一个\('\#'\)
#include<bits/stdc++.h>
using namespace std;
char s[22000703];
int R[22000703],len;
void read() {
char ch=getchar();
s[0]='~';s[++len]='#';
while(ch>'z'||ch<'a') ch=getchar();
while(ch>='a'&&ch<='z') s[++len]=ch,s[++len]='#',ch=getchar();
}
int main () {
read();
int r=0,mid=0,ans=0;
for(int i=1;i<=len;i++) {
if(i<=r) R[i]=min(R[2*mid-i],r-i+1);
while(s[i-R[i]]==s[i+R[i]]&&s[i-R[i]]!='~') ++R[i];
if(r<i+R[i]) {
r=i+R[i]-1;
mid=i;
}
ans=max(ans,R[i]);
}
printf("%d",ans-1);
return 0;
}
跟风Manacher算法整理的更多相关文章
- 浅谈Manacher算法与扩展KMP之间的联系
首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解.网上解法颇多.时间复杂度也不尽同样,这里列述几种常见的解法. 解法一 ...
- ACM -- 算法小结(八)字符串算法之Manacher算法
字符串算法 -- Manacher算法 首先介绍基础入门知识,以下这部分来着一贴吧,由于是很久之前看的,最近才整理一下,发现没有保存链接,请原创楼主见谅. //首先:大家都知道什么叫回文串吧,这个算法 ...
- HDU3068 回文串 Manacher算法
好久没有刷题了,虽然参加过ACM,但是始终没有融会贯通,没有学个彻底.我干啥都是半吊子,一瓶子不满半瓶子晃荡. 就连简单的Manacher算法我也没有刷过,常常为岁月蹉跎而感到后悔. 问题描述 给定一 ...
- manacher算法专题
一.模板 算法解析:http://www.felix021.com/blog/read.php?2040 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为 ...
- lintcode最长回文子串(Manacher算法)
题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...
- 1089 最长回文子串 V2(Manacher算法)
1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 回文串是指aba.abba.cccbccc.aaaa ...
- 51nod1089(最长回文子串之manacher算法)
题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 题意:中文题诶~ 思路: 我前面做的那道回文子串的题 ...
- LeetCode 5 Longest Palindromic Substring manacher算法,最长回文子序列,string.substr(start,len) 难度:2
https://leetcode.com/problems/longest-palindromic-substring/ manacher算法相关:http://blog.csdn.net/ywhor ...
- 求最长回文子串:Manacher算法
主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...
随机推荐
- react保存用户的输入换行,空格等等
<div dangerouslySetInnerHTML = {{ __html: '接口返回值' }} />
- 【shell】sed后向引用替换文本
要求如下: 原文 <server name="92服" port="10092" os="android" hidden=" ...
- python4---打印长方形
1:方法1for i in range(6): for j in range(3): print("*", end=" ") print() 2:输入显示长方形 ...
- 论文阅读:Andromeda: Performance, Isolation, and Velocity at Scale in Cloud Network Virtualization (全文翻译用于资料整理和做PPT版本,之后会修改删除)
Abstract: This paper presents our design and experience with Andromeda, Google Cloud Platform’s net ...
- 简单记录一下vue生命周期及 父组件和子组件生命周期钩子执行顺序
首先,vue生命周期可以用下图来简单理解 当然这也是官方文档的图片,详细的vue周期详解请参考这里 然而当同时存在父子组件的时候生命周期钩子是如何执行的呢? 请看下文: 加载渲染过程父beforeCr ...
- JDK源码--HashMap(之resize)
1.HashMap源码阅读目标了解具体的数据结构(hash及冲突链表.红黑树)和重要方法的具体实现(hashCode.equals.put.resize...) 2.重要方法 hashCode 与 e ...
- linux日常---2、lamp.sh安装lamp环境中的linux操作
linux日常---2.lamp.sh安装lamp环境中的linux操作 一.总结 一句话总结: 学不如用,学一百遍还不如真正多用几遍的来的效果好 1.linux下查看进程命令? ps 常用 ps - ...
- Electron-Vue工程初始化,以及需要掌握的相关知识
1.安装nodejs 下载地址:http://nodejs.cn/ 需要重启系统 2.安装electron npm install electron -g 3.安装vue npm install vu ...
- CentOS7--删除virbr0
https://blog.csdn.net/aienjoy/article/details/78994128
- 1、VMware安装步骤
最后重启电脑