Pagini recente » Cod sursa (job #3203217) | Cod sursa (job #1476884) | Cod sursa (job #1286993) | Cod sursa (job #743326) | Cod sursa (job #2628759)
#include <bits/stdc++.h>
#define maxn 16400
std::ifstream fin ("substr.in");
std::ofstream fout ("substr.out");
int suffix[maxn];
struct str{
int first, second;
int ind;
};
bool comp (str a, str b){
if (a.first != b.first)
return a.first < b.first;
return a.second < b.second;
}
void suffixArray (std::string &s){
int i, j, ind[s.size()];
std::vector <str> v(s.size());
for (i=0; i<s.size(); i++){
v[i].first = s[i] - 'a';
if (i + 1< s.size())
v[i].second = s[i+1]-'a';
else
v[i].second = -1;
v[i].ind = i;
}
std::sort (v.begin(), v.end(), comp);
for (j=2; j<s.size(); j*=2){
for (i=0; i<s.size(); i++)
ind[v[i].ind] = i;
int rank = v[0].first;
v[0].first = 0;
for (i=1; i<s.size(); i++){
if (v[i].first == rank and v[i].second == v[i-1].second)
v[i].first = v[i-1].first;
else{
rank = v[i].first;
v[i].first = v[i-1].first + 1;
}
}
for (i=0; i<s.size(); i++){
int pos = v[i].ind + j;
if (pos < s.size())
v[i].second = v[ind[pos]].first;
else
v[i].second = -1;
}
std::sort (v.begin(), v.end(), comp);
}
for (i=0; i<s.size(); i++)
suffix[i] = v[i].ind;
}
int lcp[maxn];
void Lcp (std::string &s){
int ind[s.size()], i, j;
for (i=0; i<s.size(); i++)
ind[suffix[i]] = i;
for (i=0, j=0; i<s.size(); i++){
if (ind[i] == s.size()-1){
j = 0;
continue;
}
int next = suffix[ind[i]+1];
while (i+j < s.size() and next+j < s.size() and s[i+j] == s[next+j])
j++;
lcp[ind[i]] = j;
if (j) j--;
}
}
bool verif (int k, int lenght, std::string &s){
for (int i=0, j=1; i<s.size(); i++, j=1){
while (j < k and i <= s.size()-1 and lcp[i] >= lenght)
i++, j++;
if (j >= k)
return true;
}
return false;
}
int main()
{
int n, k, i, j;
std::string s;
fin >> n >> k;
fin >> s;
suffixArray(s);
/*
for (i=0; i<s.size(); i++)
fout << suffix[i] << ' ';
fout << '\n';
for (i=0; i<s.size(); i++){
for (j=suffix[i]; j<s.size(); j++)
fout << s[j];
fout << '\n';
}
for (i=0; i<s.size(); i++)
fout << lcp[i] << ' ';
*/
Lcp (s);
int left = 1, right = s.size();
while (left <= right){
int mid = (left + right) / 2;
if (verif(k, mid, s) == true)
left = mid + 1;
else
right = mid - 1;
}
fout << left-1 << '\n';
return 0;
}