CF961F
简要题意
给一个长度为
题解
注意到一个惊人的事实:对于所有
因此我们发现,如果我们从中间向两边扩展,即
证明很简单,就相当于你往两边各插入一个字符,那么
那我们只需要在
由于每次
代码非常简短。
#include<cstdio>
const int N=1000005;
const int mod=1000000007;
int n,m,pw[N],hsh[N],f[N],ans; char s[N];
inline int gethash(int l,int r){
int k=r-l+1;
return (hsh[r]+mod-1ll*pw[k]*hsh[l-1]%mod)%mod;
}
main(){
scanf("%d%s",&n,s+1); m=(n-1)/2;
pw[0]=1; for(int i=1;i<=n;i++) pw[i]=pw[i-1]*131ll%mod;
for(int i=1;i<=n;i++) hsh[i]=(hsh[i-1]*131ll+s[i]-'a')%mod;
f[m+1]=-1;
for(int i=m;~i;i--){
f[i]=f[i+1]+2;
while(~f[i] && i*2+f[i]>=n) f[i]-=2;
while(~f[i] && gethash(i+1,i+f[i]) != gethash(n-i-f[i]+1,n-i) ) f[i]-=2;
}
for(int i=0;i<=m;i++) printf("%d%c",f[i],i==(n-1)/2?'\n':' ');
}