#include<cstdio>
#include<algorithm>
#include<list>
#include<cstring>
#include<iostream>
#include<bitset>
//#define int long long
using namespace std;
int kmp[1000003],len1,len2,j;
char a[1000003],b[10000003];
int main()
{
cin>>a+1;
cin>>b+1;
len1=strlen(a+1);
len2=strlen(b+1);
for(int i=2;i<=len2;i++)
{
while(j&&b[i]!=b[j+1])
{
j=kmp[j];
}
if(b[j+1]==b[i])j++;
kmp[i]=j;
}
j=0;
for(int i=1;i<=len1;i++)
{
while(j&&b[j+1]!=a[i])
{
j=kmp[j];
}
if(b[j+1]==a[i])
{
j++;
}
if(j==len2)
{
printf("%d\n",i-len2+1);
j=kmp[j];
}
}
for(int i=1;i<=len2;i++)
{
printf("%d ",kmp[i]);
}
}
要注意一点就是,当匹配成功时,有j=kmp[j][和j=0两种使用情景。前者用于普通的kmp匹配,就是匹配成功时,匹配串的后缀会对上文本串的前缀,但当j=0时,会把已成功匹配的字符串全部丢掉,会重新开始匹配,例如hdu 2087和1686,是非常好的例子