P3805 【模板】manacher算法

Aimee

马拉车算法,以优秀复杂度求解回文子串

我认为的关键:减少重复计算

用r表示当前已知回文子串右边界,id表示其中心的位置

显然我们当下求解的i应该再id右边

如果这个i在r的左边,那么显然在id的中心中,因该有一个关于i的对称点,并且因为位置的的原因,左边点的回文是已经被算出来了的,那样可以直接解决i到r部分的回文

然而更远的部分呢?就需要暴力扩展

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
string s,ss;
int id;
int r;
int p[110000001];
int Aimee;
int main(){
	cin>>s;
	int l=s.length();	
	for(int i=0;i<l;++i){
		ss+='*';
		ss+=s[i];
	}
	ss+='*';
	s=ss;
	 l=s.length();
	for(int i=0;i<l;++i){
		if(i<=r){
			p[i]=min(p[(id<<1)-i],r-i+1);
		}
		while(i-p[i]>=0&&i+p[i]<l&&s[i+p[i]]==s[i-p[i]]){
			p[i]++;
		}
		if(p[i]+i>r){
			r=p[i]+i-1;
			id=i;
		}
		Aimee=max(Aimee,p[i]);
	}
	cout<<Aimee-1<<endl;
	return 0;
}
posted @ 2021-02-02 17:13  Simex  阅读(34)  评论(0编辑  收藏  举报