[codeforces 1326D2] Prefix-Suffix Palindrome (Hard version) Manacher算法 马拉车算法

Codeforces Global Round 7   比赛人数10630

[codeforces 1326D2] Prefix-Suffix Palindrome (Hard version)   Manacher算法 马拉车算法

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

也在线测评地址https://codeforces.ml/contest/1326/problem/D2

ProblemLangVerdictTimeMemory
D2 - Prefix-Suffix Palindrome (Hard version) GNU C++11Accepted93 ms11600 KB

Manacher算法 马拉车算法 查找一个字符串的最长回文子串的线性算法

AC代码如下

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1000010
char s[maxn],mid[maxn],tmp[maxn<<1];
int Len[maxn<<1];
using namespace std;
void init(char *ss,int n){
	int i;
	tmp[0]='$';
	for(i=1;i<=n*2;i+=2){
		tmp[i]='#';
		tmp[i+1]=ss[(i+1)/2];
	}
	tmp[n*2+1]='#',tmp[n*2+1+1]=0;
}
int Manacher(){
	int i,n,j,mx,P,p0,lmax=0,rmax=0;
	n=strlen(tmp+1),mx=1,p0=1,Len[1]=1;
	for(i=1;i<=n-1;i++){
		if(i<=mx)Len[i]=min(mx-i+1,Len[2*p0-i]);
		else Len[i]=1;//i>=mx
		while(tmp[i-Len[i]]==tmp[i+Len[i]])Len[i]++;
		if(mx<i+Len[i]-1)mx=i+Len[i]-1,p0=i;
		if(i==Len[i])lmax=max(lmax,Len[i]-1);
		if(i+Len[i]-1==n)rmax=max(rmax,Len[i]-1);
	}
	if(lmax>rmax)return lmax;
	else return -rmax;
}
int main(){
	int l,r,i,t,ls,n,offset;
	scanf("%d",&t);
	while(t--){
		scanf("%s",s+1);
		ls=strlen(s+1);
		l=1,r=ls;
		while(l<r&&s[l]==s[r])l++,r--;
		for(i=1;i<l;i++)printf("%c",s[i]);
		n=r-l+1;//中间剩下字串长度
		if(n>0){
			for(i=l;i<=r;i++)mid[i-l+1]=s[i];
			mid[n+1]=0;
			init(mid,n);
			offset=Manacher();
			if(offset>0)
				for(i=l;i<=l+offset-1;i++)printf("%c",s[i]);
			else 
				for(i=r+offset+1;i<=r;i++)printf("%c",s[i]);
		}
		for(i=r+1;i<=ls;i++)printf("%c",s[i]);
		printf("\n");
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值