POJ-2774 字符串哈希+二分

题意:给出s,t两个字符串,求最长公共子串的长度

思路:首先二分答案x,预处理出s中长度为x的子串哈希值并排序,在t中枚举起点,二分查找t[i...i+x]的哈希值

二分查找直接用binary_search()函数

复杂度其实是nlog方

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define LL long long
 6 #define uLL unsigned long long
 7 #define debug(x) cout << "[" << x << "]" << endl
 8 using namespace std;
 9 
10 const int mx = 1e5+10;
11 const int base = 131;
12 char s[mx], t[mx];
13 uLL hs[mx], ht[mx], a[mx], p[mx];
14 int n, m;
15 
16 bool check(int x){
17     int cnt = 0;
18     for (int i = x; i <= n; i++)
19         a[cnt++] = hs[i]-p[x]*hs[i-x];
20     sort(a, a+cnt);
21     for (int i = x; i <= m; i++){
22         uLL k = ht[i]-p[x]*ht[i-x];
23         if (binary_search(a, a+cnt, k)) return 0;
24     }
25     return 1;
26 }
27 
28 int main(){
29     p[0] = 1;
30     scanf("%s%s", s+1, t+1);
31     n = strlen(s+1), m = strlen(t+1);
32     for (int i = 1; i <= n; i++) hs[i] = hs[i-1]*base+s[i]-'a';
33     for (int i = 1; i <= m; i++) ht[i] = ht[i-1]*base+t[i]-'a';
34     for (int i = 1; i <= max(n, m); i++) p[i] = p[i-1]*base;
35     int l = 0, r = min(n, m);
36     while (l <= r){
37         int mid = (l+r)>>1;
38         if (check(mid)) r = mid-1;
39         else l = mid+1;
40     }
41     printf("%d\n", r);
42     return 0;
43 }

 

posted @ 2018-09-30 23:58  QAQorz  阅读(390)  评论(0编辑  收藏  举报