-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathSPOJ21683.cc
68 lines (63 loc) · 1.47 KB
/
SPOJ21683.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// SPOJ 21683: Bhagat and String
// http://www.spoj.com/problems/BGTSTR/
//
// Solution: rolling hash
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <unordered_map>
#include <cstring>
using namespace std;
#define fst first
#define snd second
#define all(c) ((c).begin()), ((c).end())
typedef long long ll;
struct rolling_hash {
static const unsigned long long p = 1000000007ull;
const char *s;
int n;
vector<ll> pow, phash;
rolling_hash(const char *s) : s(s), n(strlen(s)), pow(n+1), phash(n+1) {
pow[0] = 1; phash[0] = 0;
for (int i = 0; i < n; ++i) {
phash[i+1] = s[i] + phash[i] * p;
pow[i+1] = pow[i] * p;
}
}
ll hash(int i, int j) {
return phash[j] - phash[i] * pow[j-i];
}
};
void solve(char s[], int k) {
int n = strlen(s);
rolling_hash RH(s);
int lo = 0, hi = n+1, l;
while (lo + 1 < hi) {
int mid = (lo + hi) / 2;
unordered_map<ll, int> bucket;
l = -1;
for (int i = 0; i+mid <= n; ++i)
if (++bucket[RH.hash(i, i+mid)] >= k) l = i;
if (l == -1) hi = mid;
else lo = mid;
}
unordered_map<ll, int> bucket;
l = -1;
for (int i = 0; i+lo <= n; ++i)
if (++bucket[RH.hash(i, i+lo)] >= k) l = i;
if (lo == 0) {
printf("HATE\n");
} else {
printf("%d %d\n", lo, l+1);
}
}
int main() {
int ncase; scanf("%d", &ncase);
for (int icase = 0; icase < ncase; ++icase) {
char s[50010];
scanf("%s", s);
int k;
scanf("%d", &k);
solve(s, k);
}
}