zoukankan      html  css  js  c++  java
  • poj 2774 字符串哈希求最长公共子串

    Long Long Message

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <map>
    #include <string>
    #define LL long long
    #define ULL unsigned long long
    
    using namespace std;
    const int N = 1e5+10;
    
    ULL hash1[N],hash2[N],p[N];
    int seed = 131;
    char sa[N],sb[N];
    
    void init()
    {
        p[0] = 1;
        for(int i = 1; i <= 100000; i++)
        {
            p[i] = p[i-1]*seed;
        }
    }
    
    void hashs(char s[],ULL hashn[])
    {
        int len = strlen(s+1);
        hashn[0] = 0;
        hashn[1] = s[1]-'A'+1;
        for(int i = 2; i <= len; i++)
            hashn[i] = hashn[i-1]*seed + (s[i]-'A'+1);
    }
    
    ULL getHash(int pos,int len, ULL hashn[])   //获取pos位置起长度为len的子字符串哈希值
    {
        //printf("hash: %ul
    ",hashn[pos+len-1] - hashn[pos-1]*p[len]);
        return hashn[pos+len-1] - hashn[pos-1]*p[len];
    }
    
    bool check(int len, int la,int lb)
    {
        vector<ULL> bin;
        for(int i = len; i <= la; i++)
            bin.push_back(getHash(i-len+1,len,hash1));
    
        sort(bin.begin(),bin.end());
    
        for(int i = len; i <= lb; i++)
        {
            ULL temp = getHash(i-len+1,len,hash2);
            if(binary_search(bin.begin(),bin.end(),temp))
                return true;
        }
        return false;
    }
    
    void solve()
    {
        init();
        while(~scanf("%s %s",sa+1,sb+1))
        {
            hashs(sa,hash1);
            hashs(sb,hash2);
            int la = strlen(sa+1);
            int lb = strlen(sb+1);
    
            int ans = 0;
            int lf = 1,mid;
            int rt = min(la,lb);
            while(lf <= rt)
            {
                mid = (lf+rt)/2;
                if(check(mid,la,lb))
                {
                    ans = mid;
                    lf = mid+1;
                }
                else
                {
                    rt = mid-1;
                }
            }
            printf("%d
    ",ans);
        }
    }
    
    int main(void)
    {
        solve();
    
        return 0;
    }
    
    
  • 相关阅读:
    CF-1102E-Monotonic Renumeration
    判断一颗二叉树是否为二叉搜索树
    Trie树的插入,查前缀,查单词,删前缀和删单词。
    poi 生成图片到excel
    poi 生成excel,最简单代码
    poi 实战代码---导出Excel(根据模板导出)
    共分为六部完成根据模板导出excel操作
    导入报版本不匹配问题
    ftp工具类
    关于获取路径path
  • 原文地址:https://www.cnblogs.com/henserlinda/p/11738566.html
Copyright © 2011-2022 走看看