给定两个序列A和B,序列长度分别为n和m,下标从1开始,问最小的k,使Ak...Ak+m-1与B序列相同
裸KMP
#include <cstdio>
const int INF=~0u>>1;
int kmp(int s1[],int s2[],int next[]) {
int i,j,k,ans=0;
j=0;k=-1;
next[0]=-1;
while (s2[j]!=INF) {
while (k!=-1&&s2[j]!=s2[k]) k=next[k];
j++;k++;
if (s2[j]!=s2[k]) next[j]=k;
else next[j]=next[k];
}
i=j=0;
while (s1[i]!=INF) {
if (j!=-1&&s2[j]==INF) return i-j+1;
while (j!=-1&&s1[i]!=s2[j]) j=next[j];
i++;j++;
}
if (s2[j]==INF) return i-j+1;
return -1;
}
int a[1000001];
int b[10001];
int next[10001];
int main() {
int t,n,m,i;
scanf("%d",&t);
while (t--) {
scanf("%d%d",&n,&m);
for (i=0;i<n;i++) scanf("%d",&a[i]);
for (i=0;i<m;i++) scanf("%d",&b[i]);
a[n]=b[m]=INF;
printf("%d\n",kmp(a,b,next));
}
return 0;
}