[BZOJ]2342: [Shoi2011]双倍回文 manacher

题目大意:

求一个字符串中最大双倍回文串的长度(为4的倍数),整个串为回文串,它的一半也是回文串。

题解:manacher+乱搞,不知道为什么网上的大神都用各种高级的方法,可能比较快吧……但我也不慢啊……

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int Q=500005;
char ss[Q],s[Q*2];
int n,len,l,p[Q*2];
int main()
{
	scanf("%d%s",&n,ss);
    s[0]='@';s[1]='#';
    len=2;
    l=strlen(ss);
    for(int i=0;i<l;i++)
    {
        s[len++]=ss[i];
        s[len++]='#';
    }
    s[len]='$';
    int mx=0,id=0;
    p[0]=1;
    for(int i=1;i<=len;i++)
    {
        if(i<mx) p[i]=min(p[id*2-i],mx-i);
        else p[i]=1;
        while(s[i+p[i]]==s[i-p[i]]) p[i]++;
        if(p[i]+i>mx)
        {
            mx=p[i]+i;
            id=i;
        }
    }
    int ans=0;
    for(int i=1;i<=len;i+=2) 
	{
		if(p[i]%2==0 || ans>=p[i]-1) continue;
		for(int t=i-(p[i]-1)/2;t<i;t++)
		if((i-t)*2<=ans) break;
		else if((i-t)%2==0 && t+p[t]-1>=i) {ans=max(ans,(i-t)*2);break;}
	}
    printf("%d",ans);
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值