Problem Description
Mr. Frog has two sequences and and a number p. He wants to know the number of positions q such that sequence is exactly the sequence where and .
Input
The first line contains only one integer , which indicates the number of test cases.Each test case contains three lines.The first line contains three space-separated integers and .The second line contains n integers .the third line contains m integers .
Output
For each test case, output one line “Case #x: y”, where x is the case number (starting from 1) and y is the number of valid q’s.
Sample Input
2
6 3 1
1 2 3 1 2 3
1 2 3
6 3 2
1 3 2 2 3 1
1 2 3
Sample Output
Case #1: 2
Case #2: 1
AC
- 在a数组中匹配b,每次间隔p,如果每次间隔1的话,直接一个kmp就可以,但是间隔2以上就要枚举所有的区间进行kmp,要不然会漏掉
- 例如a数组:1,1,2,2,3,3,b数组:1, 2, 3 p = 2,如果只是从0开始跑kmp,只会得到1对应a数组中下标为(0,2,4),但是(1,3,5)就漏掉了
- 所以在满足可以构成M个数的前提下,保证所有的区间恰好都覆盖
#include <iostream>
#include <stdio.h>
#include <map>
#include <vector>
#include <set>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 1000005
#define ll long long
using namespace std;
int a[N], b[N], pre[N];
void get_next(int m) {
int i = 0, j = -1;
pre[0] = -1;
while (i < m) {
if (b[i] == b[j] || j == -1)
pre[++i] = ++j;
else
j = pre[j];
}
}
int kmp(int start, int n, int m, int p) {
int ans = 0;
get_next(m);
int i = start, j = 0;
while (i < n) {
if (j == -1 || a[i] == b[j])
j++, i += p;
else
j = pre[j];
if (j == m)
ans++, j = pre[j];
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int t;
scanf("%d", &t);
int Case = 1;
while (t--) {
int n, m, p;
scanf("%d%d%d", &n, &m, &p);
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 0; i < m; ++i) {
scanf("%d", &b[i]);
}
int ans = 0;
// 枚举所有区间
for (int i = 0; i < p; ++i) {
// 保证构成M个数
if (i + m * p - p <= n - 1)
ans += kmp(i, n, m, p);
else
break;
}
printf("Case #%d: %d\n", Case++, ans);
}
return 0;
}