poj 2772 Long Long Message

来源:互联网 发布:js读取html代码 编辑:程序博客网 时间:2024/06/06 05:44

求解最长公共字串使用二分+字符串哈希

二分得到长度M,然后分别哈希两个字符串长度为M的子串,看两个字符串的哈希值是否有相等的,然后不断二分直到长度最大。

#include <algorithm>#include <iostream>  #include <cstring>    #include <cstdio>    #include <vector>  #include <queue>  #include <map>    using namespace std;    const long long B = 1e8+7;const int MAX = 100010;int n,m;char s1[MAX],s2[MAX];long long base[MAX],hash[MAX];bool check(int len){long long tmp = 0;for(int i=0; i<len; i++)tmp = tmp * B + s1[i];hash[0] = tmp;for(int i=0; i<=n-len; i++)hash[i+1] = hash[i]*B + s1[i+len] - s1[i]*base[len];//通过一个哈希值求所有长度为len的字串的哈希值(B进制的数字)sort(hash, hash+n-len+1);//二分查找先排序long long Hash = 0;for(int i=0; i<len; i++) Hash = Hash*B + s2[i];for(int i=0; i<m-len+1; i++){if(binary_search(hash, hash+n-len+1, Hash)) return true;Hash = Hash*B + s2[i+len]-s2[i]*base[len];}return false;}int main(){base[0] = 1;for(int i=1; i<MAX; i++) base[i] = base[i-1]*B;scanf("%s",s1);scanf("%s",s2);n = strlen(s1);m = strlen(s2);int ans = -1;int l = 0, r = min(n, m);while(l <= r){int mid = (l + r) >> 1;if(check(mid)){//mid可行那么向右查找是否有更大的答案l = mid + 1;ans = mid;}else r = mid - 1;}printf("%d\n",ans);}



0 0