求满足 aq,aq+p,aq+2p,,aq+(m-1)p=b1..bm 的子串数
a[i]=b[j] 主串i+=p 则把主串分组 每组长度为a/p,进行kmp匹配即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int a[N],b[N],c[N];
int fail[N];//fail[i] 在i失配时回溯到fail[i]
int n,m,p,ans;
void Fail()
{
int k=-1,i=0;
fail[0]=-1;
while(i<m)
{
if(k==-1||b[i]==b[k])
{
fail[i+1]=k+1;
i++;
k++;
}
else
k=fail[k];
}
}
void kmp(int s[],int len) {
int i,k=0,ret=0;
for (i=0;i<len;i++) {
while (k>0&&b[k]!=s[i]) k=fail[k];
if (b[k]==s[i]) k++;
if (k==m) ans++,k=fail[k];
}
}
int main()
{
int t;
cin>>t;
for(int cas=1;cas<=t;cas++)
{
ans=0;
cin>>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]);
Fail();
for(int q=0;q<p&&q<n;q++)//枚举起点,每组的长度为n/p 总共p组
{
int j;
for(j=0;q+j*p<n;j++)//
{
c[j]=a[q+j*p];
}
kmp(c,j);
}
printf("Case #%d: ",cas);
cout<<ans<<endl;
}
return 0;
}