[模板] manacher算法

Posted lr599909928

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[模板] manacher算法相关的知识,希望对你有一定的参考价值。

  1. 在字符串的头部插入‘$‘,在每个字符之间插入‘#‘.

  2. 用p数组记录以某点为中心的最长回文半径,会发现,最长回文子串长度(maxlenth=p[i]-1).

  3. 那么如何去求p数组呢?我们遍历每个字符,记录回文串能延伸到的最右端的位置(mx),之后我们再去判断.

  4. (1) mx>i: 1:i的右边界小于mx,那么因为在mx的范围内都是回文串,所以当前的p[i]一定等于对称位置的p[j] (之前已经找过了).

? 技术图片

? 2:i的右边界大于mx,那么我们可以现将p[i]取为(mx-i),然后再去判断(mx)的右边是否为回文即可.

? 技术图片

(2)i超出(mx)的边界,那我们只能去暴力判断(mx)的右边了

  1. 记得更新(mx),然后维护(p[i]-1)的最大值即可得到最长回文串的长度.

  2. 代码:

    char s[N];
    char str[N];
    int id,mx;
    int p[N];
    int j;
    
    void init(){
    	id=0;mx=0;
    	me(str,0,sizeof(str));
    	me(p,0,sizeof(p));
    	int len=strlen(s);
    	str[0]=‘$‘;
    	str[1]=‘#‘;
    	j=2;
    	for(int i=0;i<len;++i){
    		str[j++]=s[i];
    		str[j++]=‘#‘;
    	}
    }
    
    void manacher(){
    	for(int i=0;i<j;++i){
    		if(i<mx) p[i]=min(mx-i,p[2*id-i]);
    		else p[i]=1;
    		for(;str[i+p[i]]==str[i-p[i]];p[i]++)
    		if(i+p[i]>mx){
    			mx=i+p[i];
    			id=i;
    		}
    	}
    }
    
    int main() {
        //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	scanf("%s",s);
    
    	init();
    	manacher();
    
    	int ans=0;
    
    	for(int i=0;i<j;++i){
    		ans=max(ans,p[i]);
    	}
    
    	printf("%d
    ",ans-1);
    
        return 0;
    }
    

以上是关于[模板] manacher算法的主要内容,如果未能解决你的问题,请参考以下文章

manacher马拉车算法

P3805 模板manacher算法(马拉车)

[洛谷P3805]模板manacher算法

模板:Manacher算法(马拉车算法)

P3805 模板manacher算法

manacher算法模板