SP10079 STAMMER - Stammering Aliens 题解

二分这个最大长度,设当前二分中点为 $k$。

把所有长度为 $k$ 的子串算出来,扔进哈希表里。

然后如果某哈希值的出现次数 $\ge m$,则 $k$ 合法。

复杂度 $O(n\log n)$,可以过掉。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#define M 1000000093
using namespace std;
int n, m, l, r, k, f, q;char s[40050];long long p[40050], h[40050];
bool C(int k, int &q)
{
    __gnu_pbds::gp_hash_table<int, int> c, d;
    q = -1;for(int i = k, g;i <= n;++i)
        ++c[g = (h[i] + M - h[i - k] * p[k] % M) % M], d[g] = i - k + 1;
    for(auto i : c) if(i.second >= m) q = max(q, d[i.first]);return ~q;
}
int main()
{
    for(int i = p[0] = 1;i <= 40000;++i)
        p[i] = p[i - 1] * 233 % M;
    while(~scanf("%d", &m) && m)
    {
        scanf("%s", s + 1);
        l = 0;r = n = strlen(s + 1);
        for(int i = 1;i <= n;++i)
            h[i] = (h[i - 1] * 233 + s[i]) % M;
        while(l <= r) if(C(k = l + r >> 1, f))
            l = k + 1, q = f;else r = k - 1;
        if(r) printf("%d %d\n", r, q - 1);
        else puts("none");
    }
    return 0;
}
posted @ 2023-03-20 08:41  5k_sync_closer  阅读(2)  评论(0编辑  收藏  举报  来源