Pagini recente » Cod sursa (job #1781174) | Monitorul de evaluare | Cod sursa (job #212344) | Rating Delia Dabelea (Delia_D) | Cod sursa (job #2385440)
#include <algorithm>
#include <fstream>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
using Triplet = tuple<int, int, int>;
vector<vector<int>> GetPrefixes(const string &str)
{
vector<pair<char, int>> chars(str.size());
for (size_t i = 0; i < str.size(); i += 1) {
chars[i] = {str[i], i};
}
sort(chars.begin(), chars.end());
vector<vector<int>> d(str.size());
auto order = 0;
for (size_t i = 0; i < str.size(); i += 1) {
if (i > 0 && chars[i].first != chars[i - 1].first) {
order += 1;
}
d[chars[i].second].push_back(order);
}
for (size_t k = 1; (1 << k) < (int)str.size(); k += 1) {
vector<Triplet> vec(str.size());
for (size_t i = 0; i < str.size(); i += 1) {
get<0>(vec[i]) = d[i][k - 1];
get<1>(vec[i]) = (i + (1 << (k - 1))) < d.size() ? d[i + (1 << (k - 1))][k - 1] : -1;
get<2>(vec[i]) = i;
}
sort(vec.begin(), vec.end());
auto order = 0;
for (size_t i = 0; i < str.size(); i += 1) {
if (i > 0) {
auto pair1 = make_pair(get<0>(vec[i - 1]), get<1>(vec[i - 1]));
auto pair2 = make_pair(get<0>(vec[i]), get<1>(vec[i]));
order += (pair1 != pair2 ? 1 : 0);
}
d[get<2>(vec[i])].push_back(order);
}
}
return d;
}
int GetMaxPrefix(const vector<vector<int>> &prefix, int a, int b)
{
int k = prefix[a].size() - 1;
int res = 0;
while (k >= 0) {
if (prefix[a][k] == prefix[b][k]) {
res += (1 << k);
a += (1 << k);
b += (1 << k);
if (a >= (int)prefix.size() || b >= (int)prefix.size()) {
break;
}
}
k -= 1;
}
return res;
}
int Solve(const string &str, int times)
{
auto prefix = GetPrefixes(str);
vector<pair<int, int>> pairs(str.size());
for (size_t i = 0; i < str.size(); i += 1) {
pairs[i] = {prefix[i].back(), -(int)i};
}
sort(pairs.begin(), pairs.end());
vector<int> order(str.size());
for (size_t i = 0; i < str.size(); i += 1) {
order[i] = -pairs[i].second;
}
auto res = 0;
for (size_t i = 0; i + times - 1 < str.size(); i += 1) {
auto o1 = order[i];
auto o2 = order[i + times - 1];
res = max(res, GetMaxPrefix(prefix, o1, o2));
}
return res;
}
int main()
{
ifstream fin("substr.in");
ofstream fout("substr.out");
int len, times;
fin >> len >> times;
fin.get();
if (times == 1) {
fout << len << "\n";
return 0;
}
string str;
getline(fin, str);
auto res = Solve(str, times);
fout << res << "\n";
return 0;
}