Pagini recente » Cod sursa (job #1362229) | Cod sursa (job #2179730) | sim000100 | Cod sursa (job #1836563) | Cod sursa (job #2390893)
#include <algorithm>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
struct SortData
{
pair<int, int> halves;
int index;
bool operator<(const SortData &other) const
{
return halves < other.halves;
}
bool operator!=(const SortData &other) const
{
return halves != other.halves;
}
};
vector<int> Normalise(const string &str)
{
vector<SortData> sorted(str.size());
for (size_t i = 0; i < str.size(); i += 1) {
sorted[i].halves = {str[i], -1};
sorted[i].index = i;
}
sort(sorted.begin(), sorted.end());
vector<int> normal(str.size());
normal[sorted[0].index] = 0;
for (size_t i = 1; i < str.size(); i += 1) {
normal[sorted[i].index] = normal[sorted[i - 1].index];
if (sorted[i] != sorted[i - 1]) {
normal[sorted[i].index] += 1;
}
}
return normal;
}
vector<vector<int>> GetOrder(const string &str)
{
vector<vector<int>> order;
order.push_back(Normalise(str));
for (auto i = 1; (1 << (i - 1)) <= (int)str.size(); i += 1) {
vector<SortData> sorted(str.size());
for (size_t j = 0; j < str.size(); j += 1) {
sorted[j].index = j;
sorted[j].halves.first = order[i - 1][j];
if (j + (1 << (i - 1)) < str.size()) {
sorted[j].halves.second = order[i - 1][j + (1 << (i - 1))];
} else {
sorted[j].halves.second = -1;
}
}
sort(sorted.begin(), sorted.end());
order.push_back(vector<int>(str.size()));
order[i][sorted[0].index] = 0;
for (size_t j = 1; j < str.size(); j += 1) {
order[i][sorted[j].index] = order[i][sorted[j - 1].index];
if (sorted[j] != sorted[j - 1]) {
order[i][sorted[j].index] += 1;
}
}
}
return order;
}
int FindLongestPrefix(const vector<vector<int>> &order, size_t x, size_t y)
{
auto res = 0;
for (int i = order.size() - 1; i >= 0; i -= 1) {
if (x + (1 << i) > order[0].size() || y + (1 << i) > order[0].size()) {
continue;
}
if (order[i][x] == order[i][y]) {
res += (1 << i);
x += (1 << i);
y += (1 << i);
}
}
return res;
}
int FindSubstrLen(const string &str, int times)
{
auto order = GetOrder(str);
auto res = 0;
vector<int> sorted(str.size());
for (size_t i = 0; i < str.size(); i += 1) {
sorted[order.back()[i]] = i;
}
for (size_t i = 0; i + times <= str.size(); i += 1) {
auto a = sorted[i];
auto b = sorted[i + times - 1];
res = max(res, FindLongestPrefix(order, a, b));
}
return res;
}
int main()
{
ifstream fin("substr.in");
ofstream fout("substr.out");
int len, times;
fin >> len >> times;
fin.get();
string str;
getline(fin, str);
auto res = FindSubstrLen(str, times);
fout << res << "\n";
return 0;
}