码迷,mamicode.com
首页 > 编程语言 > 详细

[模板] manacher算法

时间:2020-07-31 14:09:26      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:image   lse   scanf   ++i   print   turn   str   als   ++   

  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\n",ans-1);
    
        return 0;
    }
    

[模板] manacher算法

标签:image   lse   scanf   ++i   print   turn   str   als   ++   

原文地址:https://www.cnblogs.com/lr599909928/p/13409310.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!