P3805&&ybtoj【字符串算法】2章2题【【模板】manacher算法】

【模板】manacher算法

题目

P3805


解析

关于回文子串问题,有很多种做法:
1, O ( n 3 ) O(n^3) O(n3)
直接 O ( n 2 ) O(n^2) O(n2)枚举,然后 O ( n ) O(n) O(n)判断
2, O ( n 2 ) O(n^2) O(n2)
O ( n ) O(n) O(n)枚举中点, O ( n ) O(n) O(n)扩展
3, O ( n log ⁡ n ) O(n\log n) O(nlogn)
O ( n ) O(n) O(n)枚举中点, O ( log ⁡ n ) O(\log n) O(logn)二分相等长度,哈希判相等
4, O ( n ) O(n) O(n)
枚举中点,两边扩展,更新右端点(manacher)

code(洛谷):

#include<cstdio>
using namespace std;
inline int min(int x,int y){return x<y?x:y;}
int q=1,d[22000010],ans;
char a[22000010],c;
int main()
{
	a[0]='~',a[1]='|',c=getchar();
	do{a[++q]=c,a[++q]='|',c=getchar();}
	while(c<='z'&&c>='a');
	for(int i=1,mid=0,r=0;i<=q;++i)
	{
		if(i<=r)d[i]=min(d[(mid<<1)-i],r-i+1);
		while(a[i-d[i]]==a[i+d[i]])++d[i];
		if(d[i]+i>r)r=d[i]+i-1,mid=i;
		if(d[i]>ans)ans=d[i];
	}
	printf("%d",ans-1);
	return 0;
}

code(ybtoj):

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
inline int min(int x,int y){return x<y?x:y;}
int q,d[2000010],ans,cnt;
char a[2000010],c[1000010];
int main()
{
	while(1)
	{
		memset(d,0,sizeof(d));
		cin>>c+1;
		a[0]='~',a[1]='|',ans=0,q=1;
		if(c[1]=='E')break;
		do{a[++q]=c[q>>1],a[++q]='|';}while(c[q>>1]<='z'&&c[q>>1]>='a');
		for(int i=1,mid=0,r=0;i<=q;++i)
		{
			if(i<=r)d[i]=min(d[(mid<<1)-i],r-i+1);
			while(a[i-d[i]]==a[i+d[i]])++d[i];
			if(d[i]+i>r)r=d[i]+i-1,mid=i;
			if(d[i]>ans)ans=d[i];
		}
		if(cnt)printf("Case %d: %d\n",++cnt,ans-1);
		else printf("Case %d: %d\n",++cnt,ans-2);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值