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
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
D2 - Prefix-Suffix Palindrome (Hard version) | GNU C++11 | Accepted | 93 ms | 11600 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;
}