You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
/*
Rabin_Karp: 虽说用KMP更好, 但是RK算法好理解。简单说一下RK算法的原理: 首先把模式串的哈希值算出来,
在文本串里不断更新模式串的长度的哈希值,若相等,则找到了,否则整个模式串的长度的哈希值向右移动一位
*/
# include <bits/stdc++.h>
using namespace std ;
typedef unsigned long long ULL ;
const int N = 1e4 + 10 ;
const int M = 1e6 + 10 ;
const ULL KEY = 100000007 ;
int s [ M ] , p [ N ] ;
int n , m ;
int match ( ) {
ULL h = 1 ;
for ( int i = 0 ; i < n ; i + + ) h * = KEY ;
//对齐0~n-1
ULL ah = 0 , bh = 0 ;
for ( int i = 0 ; i < n ; i + + ) ah = ah * KEY + s [ i ] ; //模拟成KEY进制, 然后利用ULL溢出的形式, 相当于对2^64取模
for ( int i = 0 ; i < n ; i + + ) bh = bh * KEY + p [ i ] ;
//开始尝试匹配
for ( int i = 0 ; i < = m - n ; i + + ) {
if ( ah = = bh ) return i + 1 ; //如果HASH值一致, 则返回匹配位置, 因本题要求数组下村从1开始, 所以+1后返回
if ( i < m - n ) ah = ah * KEY + s [ i + n ] - s [ i ] * h ; //怕越界, 因为数据弱, 不写if也能AC, 但如果模式串最后一位是0, 就狒狒了, 原因看EXCEL
}
return - 1 ;
}
int main ( ) {
int T ;
scanf ( " %d " , & T ) ;
while ( T - - ) {
scanf ( " %d%d " , & m , & n ) ;
for ( int i = 0 ; i < m ; i + + ) scanf ( " %d " , & s [ i ] ) ; //源串
for ( int i = 0 ; i < n ; i + + ) scanf ( " %d " , & p [ i ] ) ; //模式串
printf ( " %d \n " , match ( ) ) ;
}
return 0 ;
}