Sequence I
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1226 Accepted Submission(s): 466
Problem Description
Mr. Frog has two sequences
a
1
,a
2
,⋯,a
n![]()
and
b
1
,b
2
,⋯,b
m![]()
and a number p. He wants to know the number of positions q such that sequence
b
1
,b
2
,⋯,b
m![]()
is exactly the sequence
a
q
,a
q+p
,a
q+2p
,⋯,a
q+(m−1)p![]()
where
q+(m−1)p≤n
and
q≥1
.
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≤10
6
,1≤m≤10
6![]()
and
1≤p≤10
6![]()
.
The second line contains n integers a
1
,a
2
,⋯,a
n
(1≤a
i
≤10
9
)
.
the third line contains m integers b
1
,b
2
,⋯,b
m
(1≤b
i
≤10
9
)
.
Each test case contains three lines.
The first line contains three space-separated integers 1≤n≤10
The second line contains n integers a
the third line contains m integers b
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.
Sample Input
2 6 3 1 1 2 3 1 2 3 1 2 3 6 3 2 1 3 2 2 3 1 1 2 3
Sample Output
Case #1: 2 Case #2: 1
Source
KMP 变形 因为每隔p个 所以再加一层循环只循环到p即可
#include <iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000010
using namespace std;
int a[maxn],b[maxn];
int n,m,p,ans,nextp[maxn];
void getnextp(){
int i=0,j=-1;
nextp[i]=j;
while(i<m){
if(j==-1||b[i]==b[j]){
i++,j++;
nextp[i]=j;
}
else
j=nextp[j];
}
}
void kmp(int start){
int i=start,j=0;
while(i<n){
if(j==-1||a[i]==b[j])
i+=p,j++;
else
j=nextp[j];
if(j==m)
ans++,j=nextp[j];
}
}
int main()
{
int t,cnt=0;
scanf("%d",&t);
while(t--){
ans=0;
scanf("%d%d%d",&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]);
getnextp();
for(int i=0;i<p;++i)
kmp(i);
printf("Case #%d: %d\n",++cnt,ans);
}
return 0;
}