Pagini recente » Cod sursa (job #3359617) | Cod sursa (job #3359627) | Borderou de evaluare (job #1151831) | Borderou de evaluare (job #2050251) | Cod sursa (job #3359619)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("substr.in");
ofstream fout("substr.out");
int n, k;
string s;
vector<int> sa, rnk, tmp, lcp;
void buildSuffixArray() {
sa.resize(n);
rnk.resize(n);
tmp.resize(n);
for (int i = 0; i < n; ++i) {
sa[i] = i;
rnk[i] = s[i];
}
for (int len = 1; len < n; len <<= 1) {
sort(sa.begin(), sa.end(), [&](int a, int b) {
if (rnk[a] != rnk[b])
return rnk[a] < rnk[b];
int ra = a + len < n ? rnk[a + len] : -1;
int rb = b + len < n ? rnk[b + len] : -1;
return ra < rb;
});
tmp[sa[0]] = 0;
for (int i = 1; i < n; ++i) {
int a = sa[i - 1];
int b = sa[i];
int a1 = rnk[a];
int b1 = rnk[b];
int a2 = a + len < n ? rnk[a + len] : -1;
int b2 = b + len < n ? rnk[b + len] : -1;
tmp[b] = tmp[a] + (a1 != b1 || a2 != b2);
}
for (int i = 0; i < n; ++i)
rnk[i] = tmp[i];
}
}
void buildLcp() {
lcp.resize(n);
for (int i = 0; i < n; ++i)
rnk[sa[i]] = i;
int h = 0;
for (int i = 0; i < n; ++i) {
int pos = rnk[i];
if (pos == 0)
continue;
int j = sa[pos - 1];
while (i + h < n && j + h < n && s[i + h] == s[j + h])
++h;
lcp[pos] = h;
if (h)
--h;
}
}
int main() {
fin >> n >> k;
fin >> s;
if (k == 1) {
fout << n << "\n";
return 0;
}
buildSuffixArray();
buildLcp();
int ans = 0;
deque<int> dq;
for (int i = 1; i < n; ++i) {
while (!dq.empty() && lcp[dq.back()] >= lcp[i])
dq.pop_back();
dq.push_back(i);
while (!dq.empty() && dq.front() <= i - (k - 1))
dq.pop_front();
if (i >= k - 1)
ans = max(ans, lcp[dq.front()]);
}
fout << ans << "\n";
return 0;
}