Analysis
难受,
1.数组开小,在家里对拍了好久,结果造的数据恰好是上限的一半,然后就不会RE。。。(manacher的数组大小需要在原数的大小上*2)
2.要求是长度>=2,注意可以取等
3.当i<mx时,
p
[
i
]
=
m
i
n
(
p
[
2
∗
i
d
−
i
]
,
m
x
−
i
)
p[i]=min(p[2*id-i],mx-i)
p[i]=min(p[2∗id−i],mx−i),不要手贱,打成了
i
−
m
x
i-mx
i−mx
唉,敲个模板而已,人生为何如此困难
但这道题还是蛮简单的,就是求出最长回文子串的中心及其长度,然后转化一下即可
Code
#include<bits/stdc++.h>
#define N 200009
using namespace std;
char st[N],rep,idx[30];
char stn[N<<1];
int Len,maxn=-1,id,p[N<<1],mx,ans;
inline void change(char ch){
int std=ch-'a';
for(int i=0;i<26;++i)
idx[i]=(i-std+26)%26+'a';
}
inline int prework(int len){
int j=1;
stn[0]='$';
stn[1]='#';
for(int i=0;i<len;++i)
{
stn[++j]=st[i];
stn[++j]='#';
}
stn[j+1]='\0';//有效位置1~j
return j;
}
inline void manacher(){
id=0;mx=0;memset(p,0,sizeof(p));
for(int i=1;i<=Len;++i){
if(i<mx) p[i]=min(p[2*id-i],mx-i);
else p[i]=1;
while(stn[i-p[i]]==stn[i+p[i]]) p[i]++;
if(i+p[i]>mx){
id=i;
mx=i+p[i];
}
if(maxn<p[i]-1){
maxn=p[i]-1;
ans=i;
}
}
}
int main(){
while(scanf("%c%s",&rep,st)!=EOF)
{
getchar();
maxn=-1;
change(rep);
Len=prework(strlen(st));
manacher();
if(maxn>=2){
int r=ans+maxn-1,l=ans-maxn+1;
int ll=l/2-1,rr=r/2-1;
printf("%d %d\n",ll,rr);
for(int i=ll;i<=rr;++i) printf("%c",idx[st[i]-'a']);
printf("\n");
}
else printf("No solution!\n");
}
return 0;
}