码迷,mamicode.com
首页 > 其他好文 > 详细

字符串hash LA 4513 Stammering Aliens

时间:2016-01-12 13:34:57      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

 

题目传送门

题意:训练之南P225

分析:二分寻找长度,用hash值来比较长度为L的字串是否相等。

#include <bits/stdc++.h>
using namespace std;

typedef unsigned long long ull;
const int N = 4e4 + 5;
const int x = 123;
ull H[N], _hash[N], xp[N];
int rk[N];
char str[N];
int m;

void get_hash(char *s, int len)  {
    H[len] = 0;
    for (int i=len-1; i>=0; --i) {
        H[i] = H[i+1] * x + (s[i] - ‘a‘);
    }
    xp[0] = 1;
    for (int i=1; i<len; ++i) {
        xp[i] = xp[i-1] * x;
    }
}

bool cmp(const int &a, const int &b) {
    return (_hash[a] < _hash[b] || (_hash[a] == _hash[b] && a < b));
}

int check(int L, int len)    {
    int cnt = 0, pos = -1, c = 0;
    for (int i=0; i<len-L+1; ++i)   {
        rk[i] = i;
        _hash[i] = H[i] - H[i+L] * xp[L];
    }
    sort (rk, rk+len-L+1, cmp);
    for (int i=0; i<len-L+1; ++i)   {
        if (i == 0 || _hash[rk[i]] != _hash[rk[i-1]])   c = 0;
        if (++c >= m)   pos = max (pos, rk[i]);
    }
    return pos;
}

int main(void)  {
    while (scanf ("%d", &m) == 1)   {
        if (!m) break;
        scanf ("%s", &str);
        int len = strlen (str);
        get_hash (str, len);
        if (check (1, len) == -1) puts ("none");
        else    {
            int l = 1, r = len + 1;
            while (r - l > 1)   {
                int mid = l + r >> 1;
                if (check (mid, len) >= 0)    l = mid;
                else    r = mid;
            }
            printf ("%d %d\n", l, check (l, len));
        }
    }

    return 0;
}

  

字符串hash LA 4513 Stammering Aliens

标签:

原文地址:http://www.cnblogs.com/Running-Time/p/5123779.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!