/*
24/2/13
KMP
洛谷 P3375 【模板】KMP
*/
#include<iostream>
using namespace std;
#include<cstring>
#include<cstdio>
const int N = 1e6+10;
char s1[N],s2[N];
int ne[N]; //next数组 next[j]的含义是:在字串的第j个字符与主串发生匹配失败时,跳到子串的next[j]的位置重新与主串当前位置比较
int m, n; //m为主串s1的长度, n为子串s2的长度
void get_next(){ //next数组构造
for(int i = 2, j = 0; i <= n; i++){
while(j && s2[i] != s2[j+1]) j = ne[j];
if(s2[i] == s2[j+1]) j++;
ne[i] = j;
}
}
void Index_KMP(){ //KMP匹配
for(int i = 1, j = 0; i <= m; i++){
while(j && s1[i] != s2[j+1]) j = ne[j];
if(s1[i] == s2[j+1]) j++;
if(j == n){
j = ne[j];
cout << i - n + 1 << endl;
}
}
}
int main(){
cin >> s1+1 >> s2+1; //输入两个字符串 下标从1开始
m = strlen(s1+1);
n = strlen(s2+1);
get_next();
Index_KMP();
for(int i = 1; i <= n;i++){ //遍历next数组
cout << ne[i] << ' ';
}
return 0;
}
//这样看来如此基础的KMP我都不会 路漫漫其修远兮
//要想输入的字符串下标从1开始 直接 cin >> s+1;就欧克了;然后像测量其长度要 strlen(s+1);