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.

42 lines
1.5 KiB

This file contains ambiguous Unicode characters!

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;
}