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

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. xtu字符串 D. 病毒侵袭

    D. 病毒侵袭 Time Limit: 1000ms Memory Limit: 32768KB 64-bit integer IO format: %I64d      Java class nam ...

  2. Cow Exhibition (01背包)

    "Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - Cows with G ...

  3. 汕头市赛srm1X T3

    给n<=100000个点的树,每个点有一个01串,长度m<=200,串的可以随时01取反,串的每一位对应权Vi,从根节点到某个节点经过决定哪些串取反后取得的最大价值为某个点的权值,求:在这 ...

  4. Gym 215177D 母亲节的礼物

    Gym 215177D 母亲节的礼物 Problem : 给n个点m条边的无向图,每个点的度数小于等于7,要求用4种不同的颜色给每个点染色,使得每个点相邻的点中最多只有一个相同颜色的点.(n<= ...

  5. hdu 5200 Trees [ 排序 离线 2指针 ]

    传送门 Trees  Accepts: 156  Submissions: 533  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 655 ...

  6. Eventquery.vbs

    https://docs.microsoft.com/en-us/previous-versions/orphan-topics/ws.10/cc772995(v=ws.10)

  7. 前端学习之- Ajax

    Ajax:页面不做刷新,直接将数据悄悄提交到后台,然后通过回调函数处理返回结果. $.Ajax({ # 提交到后台 url:'/host', # 提交到哪里 type:'POST' # 提交方式 da ...

  8. poj -1185 炮兵阵地 (经典状压dp)

    http://poj.org/problem?id=1185 参考博客:http://poj.org/problem?id=1185 大神博客已经讲的很清楚了,注意存状态的时候是从1开始的,所以初始化 ...

  9. POJ 2104 K-th Number【整体二分 + 树状数组】

    本来只是想学一下CDQ,还是先把整体二分搞懂一点. 这题窝几个月前分别用划分树,树套树,主席树和挑战上介绍的分桶法实现了一发(然而现在都忘得差不多了) 最快的是划分树,其次是主席树,然后是树套树,还有 ...

  10. struts2中的session使用

    1.1. 如何获取Session 1.1.1. 获取Session的方式 Struts2中获取Session的方式有3种,大家掌握其中任何一种都可以. 通过ActionContext.getConte ...