Long Long Message POJ - 2774

原题链接

考察:字符串匹配+hash优化+二分

错误思路:
       KMP算法是用于看一个串是否为另一个串的子串,这道题如果枚举子串,每个都求next数组再匹配时间复杂度是O(n^2)

      求公共子串长度最好不要用KMP

正确思路:
       hash算法同样是枚举给定长度的字符串,但是hash不用求next数组,利用预处理好的hash数组可以O(1)求任意子串的hash值.

       但是枚举长度以及相应字符串同样会超时,此时可以用二分优化

 1 #include <iostream>
 2 #include <cstring>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef unsigned long long ull;
 7 const int N = 100010;
 8 const int P = 133;
 9 ull h[N],p[N],ht[N];
10 char s[N],t[N];
11 int len,lens;
12 vector<ull> v;
13 ull query(int l,int r,int id)
14 {
15     if(id) return h[r]-h[l-1]*p[r-l+1];
16     else return ht[r]-ht[l-1]*p[r-l+1];
17 }
18 bool check(int mid)
19 {
20     v.clear();
21     for(int i=1;i+mid-1<=len;i++) v.push_back(query(i,i+mid-1,1));
22     sort(v.begin(),v.end());
23     for(int i=1;i+mid-1<=lens;i++){
24         ull tmp = query(i,i+mid-1,0);
25         if(binary_search(v.begin(),v.end(),tmp))  return true;
26     }
27     return false;
28 }
29 int main()
30 {
31     freopen("in.txt","r",stdin);
32     scanf("%s%s",s+1,t+1);
33     len = strlen(s+1); lens = strlen(t+1);
34     p[0] = 1;
35     for(int i=1;i<=len;i++){
36         h[i] = h[i-1]*P+s[i];
37         p[i] = p[i-1]*P;
38     }
39     for(int i=1;i<=lens;i++) ht[i] = ht[i-1]*P+t[i];
40     int low = 0; int high = min(len,lens);
41     while(low<high)
42     {
43         int mid = low+high+1>>1;
44         if(check(mid)) low = mid;
45         else high = mid-1; 
46     }
47     printf("%d\n",low);
48     return 0;
49 } 

 

posted @ 2021-01-07 00:00  acmloser  阅读(69)  评论(0编辑  收藏  举报