有些时候,后缀自动机并不能解决某些问题,或者解决很麻烦。这时就有各种神奇的字符串算法了。

manacher算法用来O(|S|)地求出字符串S的最长的回文子串的长度。这是怎么做到的呢?

并不对劲的暴力选手在刚见到求字符串S的最长的回文串的长度这个问题时,第一反应就是枚举每一个位置为回文串的对称轴,再暴力地判断。由于回文串的对称轴可能在缝隙处,对于奇偶还要特判。这时最好每隔一个字符插入一个奇怪的字符。对暴力做一些优化,就是用二分+哈希来判断。不过这也只能o(|S| log2|S|)地做出来。能不能利用回文串的某些性质呢?

设r[i]表示以i为对称轴,是S[i+1]与S[i-1],S[i+2]与S[i-2],…,S[i+x]与S[i-x],相等的最大的x。定义s(i,r[i])表示以i为对称轴的且右端点为i+r[i]的回文串。

那么i-r[i]到i+r[i]这一段就是对称的。

记已算出的最大的i+r[i]为maxr (也就是已算出的回文串的右端点中最靠右的),maxr的i为maxi。

若要算出r[a],则:

若a>=maxr,直接按定义暴力地求出r[a]。

若a<maxr,则先找出a关于maxi的对称点b。则r[a]>=min(r[b],maxr-a)。

当r[b]<maxr-a时,a+r[b]<maxr,所以s(b,r[b])肯定被s(maxi,maxr)包含。由于a与b关于maxi对称,所以以a为对称轴的回文串中,肯定有一个等于ls(b,r[b])。又因为r[b]是b的最长回文子串的右端点,所以S[b-r[b]-1]!=S[b+r[b]+1],根据对称性又能推出S[a-r[b]-1]!=S[a+r[b]+1]。所以此时r[a]=r[b]。

当r[b]>=maxr-a时,b-r[b]<maxi-r[maxi],也就是说,s(b,r[b])中有一部分在s(maxi,maxr)外,不符合对称性。这一部分是不能算的。所以此时r[a]>=min(r[b],maxr-a)

这样先令r[a]=min(r[b],maxr-i),剩下的按定义暴力求就行了。

字符串S的最长的回文串的长度就是最大的r[i]了。这是因为如果算上奇怪的字符,那么r[i]对应的回文串长度是r[i]*2+1。修改后的字符串每隔一个字符就有一个奇怪的字符。这些奇怪的字符都相同,所以r[i]对应回文串的第一个字符和最后一个字符都是奇怪的字符(形如#a#b#a#或#a#a#)。那么不是奇怪的字符一共有(r[i]*2+1-1)/2=r[i]个。

至于时间复杂度,并不对劲的人并不想不证明。因为每次有意义的比较都是maxr之后的部分,比较过的部分又会更新maxr。总的来看就是maxr将整个字符串扫了一遍,时间复杂度是O(|S|),而且很好写。

不太清楚它能出成什么题?

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define maxn 11000010
using namespace std;
char s1[maxn],s2[maxn*];
int n,mr,mid,r[maxn*],ans;
int check(int x,int y)
{
while(s2[x-y]==s2[x+y])y++;
return y-;
}
int main()
{
scanf("%s",s1+);
n=strlen(s1+);
s2[]='B',s2[n*+]='C';
for(int i=;i<=n*+;i++)
{
if(i&)s2[i]='A';
else s2[i]=s1[i/];
}n=n*+;
mr=mid=;
for(int i=;i<=n;i++)
{
if(i>=mr)
r[i]=check(i,);
else
r[i]=check(i,min(r[mid*-i],mr-i));
if(r[ans]<r[i])
ans=i;
if(i+r[i]>mr){mid=i;mr=i+r[i];}
}
printf("%d",r[ans]);
return ;
}
//Shing has healthy hands.

并不对劲的manacher

并不对劲的manacher算法的更多相关文章

  1. HDU3068 回文串 Manacher算法

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

  2. manacher算法专题

    一.模板 算法解析:http://www.felix021.com/blog/read.php?2040 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为 ...

  3. lintcode最长回文子串(Manacher算法)

    题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...

  4. 1089 最长回文子串 V2(Manacher算法)

    1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 回文串是指aba.abba.cccbccc.aaaa ...

  5. 51nod1089(最长回文子串之manacher算法)

    题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 题意:中文题诶~ 思路: 我前面做的那道回文子串的题 ...

  6. LeetCode 5 Longest Palindromic Substring manacher算法,最长回文子序列,string.substr(start,len) 难度:2

    https://leetcode.com/problems/longest-palindromic-substring/ manacher算法相关:http://blog.csdn.net/ywhor ...

  7. 求最长回文子串:Manacher算法

    主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...

  8. 【转】最长回文子串的O(n)的Manacher算法

    Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...

  9. Manacher算法

    Manacher算法是求回文串最高效的算法,能在线性时间内求出以每一个字符为中心的最长回文串.   首先,我们都能想出$O(N^2)$求出每一个字符为中心的最长回文串的算法.那么我们考虑这样一种情况. ...

随机推荐

  1. 从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧

    zoom(zoom.us) 是一款受到广泛使用的在线会议软件.相信各位一定在办公.会议.聊天等各种场景下体验或者使用过,作为一款成熟的商业软件,zoom 提供了稳定的实时音视频通话质量,以及白板.聊天 ...

  2. Go 在游戏行业中的工程实践

    在今年 1 月由七牛云主办的 ECUG Con 十周年盛会上,真有趣技术总监陈明达带来了题为< Go 在游戏行业中的工程实践>的精彩分享,深入讲解了 Go 的工程经验,错误和异常处理,in ...

  3. CSU 1307 最短路+二分

    题目大意: 帮忙找到一条a到b的最短路,前提是要保证路上经过的站点的最大距离尽可能短 这道题居然要用到二分...完全没去想过,现在想想求最大距离的最小值确实是... 这里不断二分出值代入spfa()或 ...

  4. CodeForces - 750D New Year and Fireworks

    因为 烟花的最大范围是各个方向150格 所以 最大的空间应该是 300*300 BFS和DFS均可 模拟每一个烟花爆炸的过程 但是要注意 需要一个数组来排重 在某一个爆炸点 如果爆炸的方向 和爆炸的层 ...

  5. 字符串常量与const常量内存区(——选自陈皓的博客)

    1. 一个常见的考点: char* p = "test"; 那么理利用指针p来改变字符串test的内容都是错误的非法的. 例如: p[0] = 's'; strcpy(p, &qu ...

  6. HDU 3609 二分图多重匹配

    Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  7. P1194 买礼物 洛谷

    https://www.luogu.org/problem/show?pid=1194 题目描述 又到了一年一度的明明生日了,明明想要买B样东西,巧的是,这B样东西价格都是A元. 但是,商店老板说最近 ...

  8. HDU 1041

    题意: 给原始序列1 给定变化规则是,对于原来的序列每一个0前边插入1,每个1前边插入0. 问原始序列经过n次变化之后有多少对相邻的0. 规律题: 从第二次开始 当第奇数次变化之后,数量变成原来数量的 ...

  9. Java开发笔记(一百)线程同步synchronized

    多个线程一起办事固然能够加快处理速度,但是也带来一个问题:两个线程同时争抢某个资源时该怎么办?看来资源共享的另一面便是资源冲突,正所谓鱼与熊掌不可兼得,系统岂能让多线程这项技术专占好处?果然是有利必有 ...

  10. 在SUSE12中使用 Machinery 进行高级系统管理

    简单介绍 在 SUSE Linux Enterprise 12 中.SUSE 如今推出了面向系统管理员的 Machinery.作为其高级系统管理模块的一部分.Machinery 是适用于 Linux ...