规律还是很明显的,上面的表述可以进一步转化:
2个等长的数组,满足a[i]-a[i-1]==b[i]-b[i-1]恒成立。
于是,在最开始输入的时候,只需要记录差分即可。
第1个数的值不用记录,所以我们实际上得到了n-1长的数组a和w-1长的数组b,
要求的就是问a有多少个位置可以匹配b。
#include <bits/stdc++.h>
#define MAXN 201000
using namespace std;
int next[MAXN], a[MAXN], b[MAXN];
int t[MAXN], s[MAXN];
void get_next(int p[], int lens) {
int i = 0, j = -1;
next[0] = -1;
while(i < lens) {
if(j==-1 || p[i]==p[j]) {
++i, ++j;
next[i] = j;
} else j = next[j];
}
}
int kmp(int t[], int lent, int s[], int lens) {
int ans = 0;
int i = 0, j = 0;
get_next(s, lens);
while(i < lent) {
if(j==-1 || t[i]==s[j]) {
++i, ++j;
} else j = next[j];
if(j == lens)
++ans;
}
return ans;
}
int main(void) {
int n, w;
scanf("%d%d", &n, &w);
for(int i=0; i<n; ++i)
cin >> a[i];
for(int i=0; i<w; ++i)
cin >> b[i];
for(int i=1; i<=n; ++i) {
t[i-1] = a[i]-a[i-1];
}
for(int i=1; i<=w; ++i) {
s[i-1] = b[i]-b[i-1];
}
cout << kmp(t, n, s, w-1) << endl;
return 0;
}