题解:SP10570 LONGCS - Longest Common Substring
chenrunlei · · 题解
P5546 [POI 2000 R3] 公共串的加强版。
考虑二分其长度,我们可以枚举出所有此长度的子串,那么只要判断出是不是所有给出的串都含有一个子串即可,这一点可以哈希实现,由于时限较宽松可使用 map 存哈希值(单纯不想打别的)。
然后此题变得极为简单,我们成功使用哈希取代了后缀数组 AC 了此题(实则还在 waiting。。。
具体讲解一下:我们使用进制哈希,取一个质数
:::success[code]
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100010, p = 1e9 + 7, base = 146131;
int t, n, b[N], slen[N];
string s;
vector<int> a[N];
map<int, int> mp, iop;
signed main(){
cin >> t, b[0] = 1;
for (int i = 1; i < N; i ++)
b[i] = b[i - 1] * base % p;
while (t -- && cin >> n){
for (int i = 1; i <= n; i ++){
a[i].clear(), cin >> s,
slen[i] = s.size(), a[i].push_back(0);
for (int j = 1; j <= slen[i]; j ++)
a[i].push_back((a[i][j - 1] * base + s[j - 1]) % p);
}int l = 1, r = N, ans = 0;
while (l <= r){
mp.clear();
bool flag = 0;
int mid = (l + r) >> 1;
for (int k = 1; k <= n; k ++){
iop.clear();
int lenk = slen[k];
if (lenk < mid)continue;
for (int i = 1; i <= lenk - mid + 1; i ++){
int op = (a[k][i + mid - 1] - a[k][i - 1] * b[mid] % p + p) % p;
if (!iop[op])mp[op] ++, iop[op] ++;
if (mp[op] == n){flag = 1;break;}
}
}if (flag)l = mid + 1, ans = mid;
else r = mid - 1;
}cout << ans << '\n';
}return 0;
}
::: 本人第一篇题解,看懂了留个赞吧 QWQ。