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;
}