Pagini recente » Diferente pentru documentatie/textile intre reviziile 107 si 102 | Rating Foamete Ramona (foameteramona) | Cod sursa (job #3151749) | Cod sursa (job #1664549) | Cod sursa (job #3258839)
#include <bits/stdc++.h>
#define L 16390
#define S 15
#define B 80
#define MOD 1000000123
using namespace std;
ifstream fin("substr.in");
ofstream fout("substr.out");
int n, k;
string s;
int ord[S][L], h[L], p[L], inv[L];
int qexp(int a, int b) {
int p = 1;
while (b) {
if (b % 2 == 1)
p = 1LL * p * a % MOD;
a = 1LL * a * a % MOD;
b /= 2;
}
return p;
}
void build() {
p[0] = 1;
for (int i = 1; i <= n; i++)
p[i] = 1LL * p[i - 1] * B % MOD;
inv[n] = qexp(p[n], MOD - 2);
for (int i = n - 1; i >= 0; i--)
inv[i] = 1LL * B * inv[i + 1] % MOD;
}
int getHash(int i, int j) {
return 1LL * inv[i - 1] * (h[j] - h[i - 1] + MOD) % MOD;
}
int lcp(int x, int y) {
int le = 1, ri = min(n - x, n - y) + 1, best = 0;
while (le <= ri) {
int mid = (le + ri) / 2;
if (getHash(x, x + mid - 1) == getHash(y, y + mid - 1)) {
best = mid;
le = mid + 1;
}
else
ri = mid - 1;
}
return best;
}
int main() {
fin >> n >> k >> s;
s = "#" + s;
build();
for (int i = 1; i <= n; i++) {
h[i] = (1LL * h[i - 1] + 1LL * (s[i] - '0' + 1) * p[i]) % MOD;
ord[0][i] = s[i];
}
for (int bit = 1; bit < S; bit++) {
vector <pair <pair <int, int>, int>> v;
for (int i = 1; i <= n; i++) {
if (i + (1 << (bit - 1)) > n)
v.push_back({{ord[bit - 1][i], 0}, i});
else
v.push_back({{ord[bit - 1][i], ord[bit - 1][i + (1 << (bit - 1))]}, i});
}
sort(v.begin(), v.end());
int ind = 1;
ord[bit][v[0].second] = ind;
for (int i = 1; i < n; i++) {
if (v[i].first == v[i - 1].first)
ord[bit][v[i].second] = ind;
else
ord[bit][v[i].second] = ++ind;
}
}
vector <pair <int, int>> v;
for (int i = 1; i <= n; i++)
v.push_back({ord[S - 1][i], i});
sort(v.begin(), v.end());
int ans = 0;
for (int i = 0; i <= n - k; i++)
ans = max(ans, lcp(v[i].second, v[i + k - 1].second));
fout << ans << "\n";
return 0;
}