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 }