• POJ 2774 Long Long Message (二分 + Hash 求最长公共子串)题解


    题意:求最长公共子串

    思路:把两个串Hash,然后我们把短的作为LCS的最大可能值,然后二分长度,每次判断这样二分可不可以。判断时,先拿出第一个母串所有len长的子串,排序,然后枚举第二个母串len长度字串,二分查找在第一个母串的子串中存不存在。

    代码:

    #include<cmath>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 100000 + 10;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1000000007;
    ull hs[maxn], hp[maxn], fac[maxn], q[maxn];
    int len1, len2;
    char s[maxn], p[maxn];
    ull get_hash(ull *h, int l, int r){
        return h[r] - h[l - 1] * fac[r - l + 1];
    }
    bool check(int len){
        int cnt = 0;
        for(int i = 1; i + len - 1 <= len1; i++){
            q[cnt++] = get_hash(hs, i, i + len - 1);
        }
        sort(q, q + cnt);
        for(int i = 1; i + len - 1 <= len2; i++){
            ull aim = get_hash(hp, i, i + len - 1);
            if(binary_search(q, q + cnt, aim)) return true;
        }
        return false;
    }
    int main(){
        fac[0] = 1;
        for(int i = 1; i < maxn; i++)
            fac[i] = fac[i - 1] * seed;
        while(~scanf("%s%s", s + 1, p + 1)){
            len1 = strlen(s + 1);
            len2 = strlen(p + 1);
            hs[0] = hp[0] = 0;
            for(int i = 1; i <= len1; i++)
                hs[i] = hs[i - 1] * seed + (s[i] - 'a');
            for(int i = 1; i <= len2; i++)
                hp[i] = hp[i - 1] * seed + (p[i] - 'a');
            int l = 0, r = min(len1, len2);
            int ans = 0;
            while(l <= r){
                int m = (l + r) >> 1;
                if(check(m)){
                    l = m + 1;
                    ans = m;
                }
                else{
                    r = m - 1;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    栈和堆的详细介绍
    在DataTable中执行DataTable.Select("条件")返回DataTable;
    委托和事件
    面试宝典
    sql的寫法,推薦的寫法,全文索引提高類似like查詢的效率
    Google地图
    一般处理程序中,获取session
    提交表单
    手脱tElock 0.98b1 -> tE!
    手脱FSG 2.0 -> bart/xt
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10662817.html
Copyright © 2020-2023  润新知