Sequence I
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 533 Accepted Submission(s): 210
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 q such that sequence
b1,b2,⋯,bm
is exactly the sequence aq,aq+p,aq+2p,⋯,aq+(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≤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).
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.
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
题意:
给出两个数组a,b与p,求有多少个q满足aq,aq+p,aq+2p,⋯,aq+(m−1)p等于b数组。
思路:
把a数组分为p个数组,分别于b数组进行kmp匹配。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<list>
#include<set>
#include<math.h>
#include<map>
using namespace std;
int gcd(int a,int b)
{
if(b==0)
return a;
else return gcd(b,a%b);
}
const int N=2000005;
int a[N],b[N],s[N];
int f[N];
int n,m,p;
void getfill()
{
f[0]=f[1]=0;
for(int i=1;i<m;i++)
{
int j=f[i];
while(j && b[i]!=b[j])
j=f[j];
f[i+1]=(b[i]==b[j])?j+1:0;
}
}
int find(int len)
{
int ans=0;
int j=0;
for(int i=0;i<len;i++)
{
while(j && s[i]!=b[j])
j=f[j];
if(s[i]==b[j])
j++;
if(j==m)
ans++;
}
return ans;
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
int num=1;
while(t--)
{
scanf("%d%d%d",&n,&m,&p);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<m;i++)
scanf("%d",&b[i]);
int sum=0;
getfill();
for(int i=0;i<p;i++)
{
int len=0;
for(int j=i;j<n&&i+(m-1)*p<n;j+=p)
s[len++]=a[j];
sum+=find(len);
}
printf("Case #%d: %d\n",num,sum);
num++;
}
return 0;
}