manacher算法 马拉车算法入门 模版题HDU3068

艰难的算法学习之路,看了大佬的博客之后自己边理解边敲,一开始用string写的,cin关了同步之后交是TLE,然后各种优化,TLE,然后改成char型和scanf,还是TLE???????????????

我真是个铁憨憨看来真是没理解透 ,把R=i+p[i] 写成1+p【i】
改了之后不管cin还是scanf都能过
啊!!!!!!!!!!!!!!难受

#include<iostream>
#include<algorithm>
#include<string.h>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=3e5+5;
string getT(string s)
{
	string T="%#";
	for(int i=0;i<s.length();i++)
	{
		T+=s[i];
		T+="#";
	}
	return T;
}
int p[maxn];
int manacher(string s)
{
	string T=getT(s);
	int C=0,R=0;
	int len=T.length();
	memset(p,0,sizeof p);
	for(int i=1;i<len;i++)
	{
		int i2=C-(i-C);
		int diff=R-i;
		if(diff>=0)//i在C和R之间 可以用p[i']求p[i]; 
		{
			if(p[i2]<diff)//i2没有越过左边界L 
				p[i]=p[i2];
			else//越过了就一个一个比较 
			{
				p[i]=diff;
				while(T[i+p[i]+1]==T[i-p[i]-1])
					p[i]++;
				C=i;//并且更新 C和R 
				R=p[i]+i;
			} 
		}
		else//不在就只能一个一个比较 
		{
			p[i]=0;
				while(T[i+p[i]+1]==T[i-p[i]-1])
					p[i]++;
				C=i;//并且更新 C和R 
				R=p[i]+i;
		} 
	}
	int maxn=0;
	for(int i=1;i<len;i++)
		maxn=max(maxn,p[i]);
	return maxn;
}
int main()
{
	string s;
	ios::sync_with_stdio(false);
	while(cin>>s)
		cout<<manacher(s)<<endl;
	return 0;
}

scanf

#include<iostream>
#include<cstring>
using namespace std;
const int maxn=3e5+5;
char s[maxn],T[maxn];
void getT()
{
	T[0]='%';
	int len=strlen(s);
	int k=0;
	for(int i=1;k<len;i+=2)
	{
		T[i]='#';
		T[i+1]=s[k++];
	}
	T[k*2+1]='#';
	T[k*2+2]=0;
}
int p[maxn];
int manacher()
{
	getT();
	int len=strlen(T);
	int C=0,R=0;
	memset(p,0,sizeof p);
	for(int i=1;i<len;i++)
	{
		int i2=C-(i-C);
		int diff=R-i;
		if(diff>=0)
		{
			if(p[i2]<diff)
				p[i]=p[i2];
			else
			{
				p[i]=diff;
				while(T[i+p[i]+1]==T[i-p[i]-1])
					p[i]++;
				C=i;
				R=p[i]+i;
			}
		}
		else
		{
			p[i]=0;
			while(T[i+p[i]+1]==T[i-p[i]-1])
				p[i]++;
			C=i;
			R=p[i]+i;
		}
	}
	int maxn=0;
	for(int i=1;i<len;i++)
		maxn=max(maxn,p[i]);
	return maxn;
}
int main()
{
	while(~scanf("%s",s))
	{
		printf("%d\n",manacher());
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值