1 const int maxn = 1e5 + 5;
2 int n, m; // n 主串长度, m模式串长度
3 string a, b; // a 主串, b 模式串, 下标从零开始
4 int _next[maxn], nextval[maxn];
5 void get_next() {
6 int i = 0, j;
7 j = _next[0] = -1;
8 while (i < m)
9 {
10 if (-1 == j || b[i] == b[j])
11 _next[++i] = ++j;
12 else
13 j = _next[j];
14 }
15 }
16
17 void get_nextval() {
18 int i = 0, j;
19 j = nextval[0] = -1;
20 while (i < m) {
21 if (-1 == j || b[i] == b[j]) {
22 ++i, ++j;
23 nextval[i] = (b[i] != b[j]) ? j : nextval[j];
24 }
25 else {
26 j = nextval[j];
27 }
28 }
29 }
30
31 int kmp_index(int pos) {
32 // 求模式串在主串 pos位置 字符之后的位置
33 int i = pos, j = 0;
34 while (i < n && j < m) {
35 if (-1 == j || a[i] == b[j]) {
36 ++i, ++j;
37 }
38 else {
39 j = nextval[j];
40 }
41 }
42 if (j >= m) return i - m;
43 else return -1;
44 }
45
46 int kmp_count(int pos) {
47 // 求模式串在主串中出现了几次
48 int i = pos, j = 0;
49 int ans = 0;
50 while (i < n) {
51 if (-1 == j || a[i] == b[j]) {
52 ++i, ++j;
53 if (j >= m) {
54 ++ans;
55 //q.push(i);
56 j = nextval[j];
57 }
58 }
59 else
60 j = nextval[j];
61 }
62 return ans;
63 }
64
65 int main()
66 {
67 cin >> a >> b;
68 n = a.size(); m = b.size();
69 get_next();
70 get_nextval();
71 int Index = kmp_index(0);
72 int Count = kmp_count(0);
73 cout << Index << ' ' << Count << endl;
74 return 0;
75 }