题意
给两堵墙。问a墙中与b墙顶部形状相同的区间有多少个
思路
- 将数列转化为两两之差后kmp,注意特判m==1(错第二个点的)
代码
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=200003;
int n,m,a[maxn],b[maxn],nxt[maxn];
void getnext()
{
int i=0,j=-1; nxt[0]=-1;
while(i<m){
if(j==-1||b[i]==b[j]) nxt[++i]=++j;
else j=nxt[j];
}
}
int kmp()
{
int i=0,j=0,ans=0;
while(i<n){
if(j==-1||a[i]==b[j]) ++i,++j;
else j=nxt[j];
if(j==m) ++ans,j=nxt[j];
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m); --n,--m;
if(!m) return cout<<n+1<<'
',0;
scanf("%d",&a[1]);
for(int i=0;i<n;++i) scanf("%d",&a[i+2]),a[i]=a[i+2]-a[i+1];
scanf("%d",&b[1]);
for(int i=0;i<m;++i) scanf("%d",&b[i+2]),b[i]=b[i+2]-b[i+1];
getnext();
cout<<kmp()<<'
';
return 0;
}