Manacher算法
爆肝计划
我是个只会暴力的小蒟蒻,每天面临着许多超时问题/(ㄒoㄒ)/~~
有一天,我刷着题,超时了,大佬看了说了一声:马拉车。我想了想,马不是一直拉车吗?肯定在开玩笑。
直到他让我去学学,我才知道是这个马拉车ಥ_ಥ。
-
马拉车主要应用在求一个字符串中最长的子字符串的长度,马拉车是个奇妙的算法,他巧妙的利用了线性思维解题,但是它又是局限性极高的算法,他只能解决这一类问题ㄟ( ▔, ▔ )ㄏ,所以他问的题像马拉车,那么解法一定是马拉车,不多说了
-
首先我们先想一个问题,我们如何将一个字符串的长度变成奇数?我相信你们肯定知道2n+1吧,那么我们怎么 做呢?很简单,就在这个字符串中间加上这个字符串所没有的单个字符就可以了。
-
那么接下来看图(字丑见谅)
上模板吧
#include<bits/stdc++.h>
using namespace std;
const int N=23000005;
char s[N],news[N];
int p[N];
int init()
{
int len=strlen(s);
news[0]='$',news[1]='#';
int j=2;
for(int i=0;i<len;i++)news[j++]=s[i],news[j++]='#';
news[j]='\0';
return j;
}
int manacher() //建议就着上面的图看
{
int len=init();
int ans=-N,id,mx=0;
for(int i=1;i<len;i++)
{
if(i<mx)p[i]=min(p[id*2-i],mx-i);
else p[i]=1;
while(news[i-p[i]]==news[i+p[i]])p[i]++;
if(mx<i+p[i])id=i,mx=i+p[i];
ans=max(ans,p[i]-1);
}
return ans;
}
int main()
{
scanf("%s",s);
printf("%d",manacher());
return 0;
}
模板题
洛谷 p3805
题目描述
给出一个只由小写英文字符a,b,c…y,z组成的字符串S,求S中最长回文串的长度.
字符串长度为n
输入格式
一行小写英文字符a,b,c…y,z组成的字符串S
输出格式
一个整数表示答案
输入输出样例
输入 #1
aaa
输出 #1
3
输出格式
一个整数表示答案
输入输出样例
输入 #1
aaa
输出 #1
3
代码直接用上面的就可以了
如果有那个过程不明白,欢迎评论,我会实时更新图解