HDU - 5918 Sequence I(2016年长春区域赛铜牌题)
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)
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
题解:
直接把多个串拿出来单独跑KMP。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6+10;
int A[MAXN];
int B[MAXN];
int C[MAXN];
int next1[MAXN];
void getNext(int M){
int k = -1;
int j = 0;
next1[0] = -1;//next数组最好是从0开始要不然会很麻烦
while(j<M){
if(k == -1 || B[j] == B[k]){
if(B[j+1] == B[k+1]){
next1[++j] = next1[++k];
}
else next1[++j] = ++k;
}
else {
k = next1[k];
}
}
}
int Find(int N,int M,int st){//返回匹配到的位置
int temp1 = st,temp2 = 0;
while(temp1<N && temp2<M){
if(temp2 == -1 || C[temp1] == B[temp2]){
temp1++;temp2++;
}
else{
temp2 = next1[temp2];
}
}
if(temp2 == M)return temp1-temp2;
else return -1;
}
int main(){
int T,N,M,P;
scanf("%d",&T);
for(int _=1 ; _<=T ; ++_){
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]);
int num,sum = 0;
getNext(M);
for(int i=0 ; i<P ; ++i){
num = 0;
for(int j = i;j < N && i+(M-1)*P < N;j += P)C[num++] = A[j];
int t = Find(num,M,0);
while(t != -1){
++sum;
t = Find(num,M,t+1);
}
}
printf("Case #%d: %d\n",_,sum);
}
return 0;
}