牛客字符串KMP训练题 栗酱的数列
这道题就是一道KMP模板题,但是有几个小地方要处理下:
首先我们来看看题面 传送门https://ac.nowcoder.com/acm/problem/14694
也就是说满足 (a2+b2-a1-b1)%k==0
化简之后就是 ((a2-a1)%k+(b2-b1)%k)%k==0
即 ((a[i]-a[i-1])%k+b[i]-b[i-1])%k)%k==0
得到这个结论以后就可以用kmp的原理进行了(想清楚后就是一道模板题)
上代码:
#include <bits/stdc++.h>
const int maxn=2e5+7;
using namespace std;
int t,n,m,k,ans;
int a[maxn],b[maxn],nxt[maxn],da[maxn],db[maxn];
void getnxt(){
nxt[0]=-1;
int i=0,sk=-1;
while (i<m-1){
if(sk==-1 || db[sk]==db[i])
nxt[++i]=++sk;
else
sk=nxt[sk];
}
}
void kmp(){
getnxt();
int i=0,j=0;
while (i<n-1)
{
if(j==-1 || (db[j]+da[i])%k==0)
j++,i++;
else
j=nxt[j];
if(j==m-1)
ans++,j=nxt[j];
}
}
int main(){
scanf("%d",&t);
while (t--){
ans=0;
scanf("%d %d %d",&n,&m,&k);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(i>0)
da[i-1]=(a[i]-a[i-1])%k;
if(da[i-1]<0)
da[i-1]+=k;
}
for(int i=0;i<m;i++){
scanf("%d",&b[i]);
if(i>0)
db[i-1]=(b[i]-b[i-1])%k;
if(db[i-1]<0)
db[i-1]+=k;
}
kmp();
printf("%d\n",ans);
}
return 0;
}