题意:
给出两个字符串s,t,求最大公共子串的长度k
思路:
- 二分求最大长度k
- 预处理s字符串长度为k的字串的hash值,放入一数组w[]后做排序
- 依次处理t字符串长度为k的字串的hash值,在w[]中查找是否有相同值,若有则条件满足
过程错点:
放入的数组使用set,由于插入数据量过大导致TL
_解决:使用普通数组,元素全部放入后再做排序
代码:
#include <iostream>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
unsigned long long p, f[1000000] = { 0 }, h[1000000] = { 0 }, g[1000000] = { 1 },w[1000002]; char s[100005], t[100005];
int m, n;
bool check(int k) {
int q;
//预处理f字符串长度为k的字串的hash值
for (int i = 0; i <= m - k; i++) {
w[i] = f[i + k] - f[i] * g[k];
}
sort(w, w + m - k + 1);
for (int i = 0; i <= n - k; i++) {
p = h[i + k] - h[i] * g[k];
//二分匹配
int q = lower_bound(w, w + m - k + 1, p) - w;
if (w[q]==p) return 1;
}
return 0;
}
int main()
{
cin >> s >> t; m = strlen(s); n = strlen(t);
//预处理前缀hash
for (int i = 1; i <= m; i++) {
f[i] = s[i - 1] - 'a' + 1 + f[i - 1] * 131;
g[i] = g[i - 1] * 131;
}
for (int i = 1; i <= n; i++) {
h[i] = t[i - 1] - 'a' + 1 + h[i - 1] * 131;
}
//二分求公共字串的最大长度
int l = 0, r = min(n, m)+1;//此处r初始值要再加1
while (l < r) {
int mid = (l + r) >> 1;
if (!check(mid)) r = mid;
else l = mid + 1;
}
cout << l - 1;
return 0;
}