Pagini recente » Cod sursa (job #1664864) | Cod sursa (job #673849) | Cod sursa (job #2752051) | Cod sursa (job #1548536) | Cod sursa (job #1749105)
///Centrul InfO(1)
///Niculae Alexandru Vlad
#include <bits/stdc++.h>
using namespace std;
const int log_max = 14;
const int n_max = (1 << 14) + 10;
int p[log_max+1][n_max];
pair < pair < int , int > , int > v[n_max];
int n , k;
string s;
void read_data()
{
ifstream fin("substr.in");
fin >> n >> k >> s;
s = ' ' + s;
}
void run_suffix_array()
{
int i , j;
for (i = 1; i <= n; ++i) p[0][i] = s[i] - 'a'; ///initializez p[0]
for (i = 1; (1 << i) <= n; ++i)
{
for (j = 1; j <= n; ++j)
{
v[j].first = {p[i-1][j] , (j+(1<<(i-1))<=n) ? p[i-1][j+(1<<(i-1))] : -1}; ///creez perechile
v[j].second = j; ///sufixul [j..n]
}
sort(v + 1 , v + n + 1);
for (j = 1; j <= n; ++j)
p[i][v[j].second] = p[i][v[j-1].second] + (v[j].first != v[j-1].first);
}
}
int lcp(int a , int b) ///longest common prefix
{
if (a == b) return n - a + 1;
int ret = 0;
for (int i = log_max; i >= 0; --i)
if ((1 << i) <= n && p[i][a] == p[i][b])
a += (1 << i), b += (1 << i), ret += (1 << i);
return ret;
}
///trebuie sa gasesc un prefix care apare de cel putin k ori
///deci voi lua maximul lcp-urilor pentru orice secventa de lungime k din vectorul sortat (este optim)
int get_ans()
{
int ret = 0;
for (int i = 1; i <= n - k + 1; ++i)
ret = max(ret , lcp(v[i].second , v[i+k-1].second));
return ret;
}
void print_answer()
{
ofstream fout("substr.out");
fout << get_ans() << '\n';
}
int main()
{
read_data();
run_suffix_array();
print_answer();
return 0;
}