直接套板子就行,不过这题对于我这个C版C++选手来说,太坑了,输入输出不能使用%lld,直接WA……最后把所有的输入输出全改成cin,cout才AC。。。记起来了还有一点,数组名不能取成next,否则CE。。。(我太菜了)
直接上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long N;
int M;
long long a[1000001];
long long b[10001];
int nextval[10001]; //nextval[j]表示模式串中第j个字符与主串中相应字符失配时,模式串中需重新和主串中该字符进行比较的字符的位置。
//即若有nextval[j]=k,则当前有p[1..k-1]=p[j-k+1..j-1]
void get_nextval()
{
memset(nextval,0,sizeof(nextval));
int i=1,j=0;
nextval[1]=0;
while(i<=M)
{
if(j==0||b[i]==b[j])
{
i++;
j++;
if(b[i]!=b[j])
nextval[i]=j;
else
nextval[i]=nextval[j];
}
else
j=nextval[j];
}
}
long long KMP()
{
get_nextval();
int j=1;
long long i=1;
while(i<=N&&j<=M)
{
if(j==0||a[i]==b[j])
{
i++;
j++;
}
else
j=nextval[j];
}
if(j>M)
return i-M;
else
return -1;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>N>>M;
for(long long i=1;i<=N;i++)
cin>>a[i];
for(int i=1;i<=M;i++)
cin>>b[i];
cout<<KMP()<<endl;
}
return 0;
}