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\n",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\n",ans);
    }
}

int main(void)
{
    solve();

    return 0;
}

posted on 2019-10-25 16:06  鱼泪儿  阅读(313)  评论(0编辑  收藏  举报

导航