Pagini recente » Cod sursa (job #2508083) | Cod sursa (job #780125) | Cod sursa (job #927021) | Cod sursa (job #2926356) | Cod sursa (job #2538057)
#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() {
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)
if (i && aux[i].first == aux[i - 1].first)
calc[k][aux[i].second] = calc[k][aux[i - 1].second];
else
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;
fin >> n >> k >> s;
if (n == 1)
return fout << 1, 0;
Build();
Kasai();
if (k == 1)
return fout << n, 0;
int st(0), dr(-1), ans(0);
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;
}