如你所见,我求了两遍 Z 数组,因为第二问可以通过拼接法解决,但是 l 和 r 初始化记得要比枚举变量的初始值少1,因为你在找之前求过的公共部分时,也就是 r−i+1,初始是需要特判 z0=n 和zn−1=x的,如果不这样就会直接判断 z0<1,然后就直接把 z0赋值为0,那 n呢?它的上一项 zn−1 已经预处理出来了,按理来说都设为n就没问题了啊,但是注意我们 l,r 的定义,是一个 Z−Box,是应该已经求出来的,而求出来的其实是 n−1,n是待求项,如果强行这样做的话,会导致还没比较就先继承了1的匹配长度,会出问题。
正确代码:
for(int i=1,l=0,r=0;i<n;i++)
{
if(z[i-l]<r-i+1) z[i]=z[i-l];
else
{
z[i]=max(r-i+1,0);
while(i+z[i]<n&&b[z[i]]==b[i+z[i]]) z[i]++;
l=i,r=i+z[i]-1;
}
}
for(int i=n,l=n-1,r=n-1;i<n+m;i++)
{
if(z[i-l]<r-i+1) z[i]=z[i-l];
else
{
z[i]=max(r-i+1,0);
while(i+z[i]<n+m&&b[z[i]]==b[i+z[i]]) z[i]++;
l=i,r=i+z[i]-1;
}
}