Pagini recente » Cod sursa (job #2457632) | Cod sursa (job #2219037) | Cod sursa (job #848459) | Cod sursa (job #2655983) | Cod sursa (job #2765797)
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
#define mxN 16400
int n, K;
string s, aux;
void read() {
ifstream f("substr.in");
f >> n >> K;
f >> s;
f.close();
}
int rez = -1;
pair<char, int> a[mxN];
int p[mxN], p_new[mxN];
int c[mxN], c_new[mxN];
int cnt[mxN], poz[mxN];
void count_sort() {
int i, x;
for (i = 0; i < n; i++)
cnt[i] = 0;
for (i = 0; i < n; i++)
cnt[c[i]]++;
poz[0] = 0;
for (i = 1; i < n; i++)
poz[i] = poz[i - 1] + cnt[i - 1];
for (i = 0; i < n; i++) {
x = c[p[i]];
p_new[poz[x]] = p[i];
poz[x]++;
}
for (i = 0; i < n; i++)
p[i] = p_new[i];
}
bool ok2(int ind) {
for (int i = p[ind]; i < min(s.size(), aux.size() + p[ind]); i++)
if (s[i] < aux[i - p[ind]])
return -1;
else if (s[i] > aux[i - p[ind]])
return 1;
return 0;
}
bool ok(int x) {
int st, dr, mij, poz1, poz2, c;
for (int i = 0; i < s.size() - x; i++) {
aux = s.substr(i, x);
poz1 = -1, st = 0, dr = n - 1;
while (st <= dr) {
mij = (st + dr) / 2;
c = ok2(mij);
if (c == 0 || c == 1) {
if (c == 0)
poz1 = mij;
dr = mij - 1;
}
else st = mij + 1;
}
poz2 = -1, st = 0, dr = n - 1;
while (st <= dr) {
mij = (st + dr) / 2;
c = ok2(mij);
if (c == 0 || c == -1) {
if (c == 0)
poz2 = mij;
st = mij + 1;
}
else dr = mij - 1;
}
if (poz1 != -1 && poz2 - poz1 + 1 >= K)
return 1;
}
return 0;
}
void solve() {
int i;
// suffix array O(nlogn)
s += '$';
n++;
for (i = 0; i < n; i++)
a[i] = {s[i], i};
sort(a, a + n);
for (i = 0; i < n; i++)
p[i] = a[i].second;
c[p[0]] = 0;
for (i = 1; i < n; i++)
if (a[i].first == a[i - 1].first)
c[p[i]] = c[p[i - 1]];
else c[p[i]] = c[p[i - 1]] + 1;
int k = 0;
pair<int, int> prev, cur;
while ((1 << k) < n) {
for (i = 0; i < n; i++)
p[i] = (p[i] - (1 << k) + n) % n;
count_sort();
c_new[p[0]] = 0;
for (i = 1; i < n; i++) {
cur = {c[p[i]], c[p[i] + (1 << k) % n]};
prev = {c[p[i - 1]], c[p[i - 1] + (1 << k) % n]};
if (cur == prev)
c_new[p[i]] = c_new[p[i - 1]];
else c_new[p[i]] = c_new[p[i - 1]] + 1;
}
for (i = 0; i < n; i++)
c[i] = c_new[i];
k++;
}
int st, dr, mij;
st = 1, dr = n - 1;
while (st <= dr) {
mij = (st + dr) / 2;
if (ok(mij)) {
rez = mij;
st = mij + 1;
}
else dr = mij - 1;
}
}
void output() {
ofstream g("substr.out");
g << (rez == -1 ? 0 : rez);
g.close();
}
int main() {
read();
solve();
output();
return 0;
}