Pagini recente » Cod sursa (job #2525345) | Cod sursa (job #2977679) | Cod sursa (job #2576398) | Cod sursa (job #2078861) | Cod sursa (job #2538038)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cassert>
using namespace std;
const int LOG = 15, N = 17000;
namespace SuffixArray {
int calc[LOG][N];
int sa[N], ord[N], lcp[N];///suficsii sortati, pozitia in vectorul sortat
int n, logn;
pair < pair < int, int >, int > aux[N];/// < < prima, a doua >, pozitie >
string s;
void Build(string _s) {
s = _s;
n = s.size();
assert(n != 1);
for (int i = 0; i < n; ++i)
calc[0][i] = s[i];
for (int k = 1; (1<<(k - 1)) < n; ++k) {
logn = k;///imi e prea lene sa fac separat
for (int i = 0; i < n; ++i)
aux[i] = {{calc[k - 1][i], (i + (1<<(k - 1)) < n ? calc[k - 1][i + (1<<(k - 1))] : -1)}, -i};
sort(aux, aux + n);///daca nu intra in timp o sa fac counting sort
for (int i = 0; i < n; ++i)
calc[k][-aux[i].second] = i;
}
for (int i = 0; i < n; ++i)
sa[calc[logn][i]] = i, ord[i] = calc[logn][i];
}
void Kasai() {
for (int k = 0, i = 0; i < n; ++i, k?k--:0) {
if (ord[i] == n - 1) {
k = 0;
continue;
}
int j = sa[ord[i] + 1];
while (i + k < n && j + k < n && s[i + k] == s[j + k])
k++;
lcp[ord[i]] = k;
}
}
}
using namespace SuffixArray;
int dq[N];
int main()
{
ifstream fin("substr.in");
ofstream fout("substr.out");
int n, k;
string s;
fin >> n >> k >> s;
if (n == 1)
return fout << 1, 0;
Build(s);
Kasai();
// for (int i = 0; i < n; ++i)
// fout << sa[i] << ' ';
// fout << '\n';
// for (int i = 0; i < n; ++i)
// fout << ord[i] << ' ';
// fout << '\n';
// for (int i = 0; i < n; ++i)
// fout << lcp[i] << ' ';
// fout << '\n';
// k--;
// n--;
// for (int i = 1; i <= n; ++i)
// v[i] = lcp[i - 1];
// ///bagam skyline
// int top(0);
// v[0] = v[n + 1] = 0;
// stk[++top] = 0;
// for (int i = 1; i <= n; ++i) {
// while (top && v[stk[top]] > v[i])
// --top;
// stanga[i] = stk[top];
// stk[++top] = i;
// }
// top = 0;
// stk[++top] = n + 1;
// for (int i = n; i >= 1; --i) {
// while (top && v[stk[top]] >= v[i])
// --top;
// dreapta[i] = stk[top];
// stk[++top] = i;
// }
// int ans(0);
// for (int i = 1; i <= n; ++i) {
// if (v[stanga[i]] == v[i])
// continue;
// if (dreapta[i] - stanga[i] - 1 >= k)
// ans += v[i] - max(v[stanga[i]], v[dreapta[i]]);
// }
// fout << ans;
///am citit gresit enuntul don't mind me
if (k == 1)
return fout << n, 0;
int st(0), dr(-1), ans(-1);
for (int i = 1; i < n; ++i) {
while (st <= dr && lcp[dq[dr]] >= lcp[i - 1])
--dr;
while (st <= dr && dq[st] <= i - k)
++st;
dq[++dr] = i - 1;
if (i - k >= -1)
ans = max(ans, lcp[dq[st]]);
}
fout << ans;
return 0;
}