Problem Description
Mr. Frog has two sequences
a1,a2,⋯,an
and
b1,b2,⋯,bm
and a number
p
. He wants to know the number of positions
Input
The first line contains only one integer
T≤100
, which indicates the number of test cases.Each test case contains three lines.
The first line contains three space-separated integers
1≤n≤106,1≤m≤106
and
1≤p≤106
.
The second line contains n integers
a1,a2,⋯,an(1≤ai≤109)
.
the third line contains m integers
b1,b2,⋯,bm(1≤bi≤109)
.
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.
Solution
KMP啊KMP……QAQ窝太弱了调了半个月
#include<stdio.h>
#include<cstring>
#define N 1000002
int a[N],b[N],P[N],n,m,p,ans;
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
inline void prepare()
{
P[1]=0;int j=0;
for (int i=2;i<=m;i++)
{
while (j && b[j+1]!=b[i]) j=P[j];
if (b[j+1]==b[i]) j++;
P[i]=j;
}
}
inline void find(const int &st)
{
int j=0;
for (int i=st;i<=n;i+=p)
{
while (j && b[j+1]!=a[i]) j=P[j];
if (b[j+1]==a[i]) j++;
if (j==m) ans++,j=P[j];
}
}
int main()
{
for (int t=1,T=read();t<=T;t++)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(P,0,sizeof(P));
n=read();m=read();p=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=m;i++) b[i]=read();prepare();
for (int i=1;i<=p;i++) find(i);
printf("Case #%d: %d\n",t,ans);ans=0;
}
}