Pagini recente » Cod sursa (job #1789675) | Cod sursa (job #2187972) | Cod sursa (job #2324169) | Cod sursa (job #2225257) | Cod sursa (job #1823546)
#include <algorithm>
#include <fstream>
#include <iostream>
#include <limits>
#include <vector>
using namespace std;
template<class T>
class SuffixArrays {
public:
// Must be indexed from 0.
explicit SuffixArrays(const vector<T>& array) :
array_(array), array_size_(array.size()) {
min_value_ = numeric_limits<T>::max();
for (char ch : array) {
min_value_ = min(min_value_, ch);
}
}
void Build() {
suffix_.resize(GetLog(array_.size()));
for (int i = 0; i < suffix_.size(); i++) {
suffix_[i].resize(array_.size());
}
for (int i = 0; i < array_size_; i++) {
suffix_[0][i] = array_[i] - min_value_;
}
for (int step = 1; step < suffix_.size(); step++) {
int length = 1 << (step - 1);
piece_.clear();
for (int i = 0; i < array_size_; i++) {
int current_left_piece = suffix_[step - 1][i];
int current_right_piece = (i + length < array_size_) ?
suffix_[step - 1][i + length] : -1;
int current_index = i;
piece_.emplace_back(current_left_piece, current_right_piece, current_index);
}
sort(piece_.begin(), piece_.end());
for (int i = 0; i < array_size_; i++) {
if (i > 0 && piece_[i] == piece_[i - 1]) {
suffix_[step][piece_[i].index_] = suffix_[step][piece_[i - 1].index_];
} else {
suffix_[step][piece_[i].index_] = i;
}
}
}
sorted_indexes_.resize(array_size_);
for (int i = 0; i < array_size_; i++) {
sorted_indexes_[suffix_[suffix_.size() - 1][i]] = i;
}
}
vector<int> GetSortedIndexes() {
if (sorted_indexes_.empty()) {
Build();
}
return sorted_indexes_;
}
int GetLongestCommonPrefix(int index_x, int index_y) {
if (suffix_.empty()) {
Build();
}
int lcp = 0;
for (int i = suffix_.size() - 1; i >= 0 && index_x < array_size_
&& index_y < array_size_; i--) {
int length = 1 << i;
if (suffix_[i][index_x] == suffix_[i][index_y]) {
lcp += length;
index_x += length;
index_y += length;
}
}
return lcp;
}
private:
struct ArrayPiece {
int left_piece_;
int right_piece_;
int index_;
ArrayPiece(const int left_piece, const int right_piece, const int index) :
left_piece_(left_piece), right_piece_(right_piece), index_(index) {}
bool operator < (const ArrayPiece& other) const {
if (this->left_piece_ == other.left_piece_) {
return this->right_piece_ < other.right_piece_;
}
return this->left_piece_ < other.left_piece_;
}
bool operator == (const ArrayPiece& other) const {
return this->left_piece_ == other.left_piece_
&& this->right_piece_ == other.right_piece_;
}
};
int GetLog(int x) const {
int log = 0;
do {
log++;
x /= 2;
} while (x);
return log;
}
const int array_size_;
const vector<T> array_;
T min_value_;
vector<vector<int>> suffix_;
vector<ArrayPiece> piece_;
vector<int> sorted_indexes_;
};
int main() {
cin.sync_with_stdio(false);
ifstream cin("substr.in");
ofstream cout("substr.out");
int n, k;
cin >> n >> k;
string s;
cin >> s;
vector<char> v;
for (char it : s) {
v.push_back(it);
}
SuffixArrays<char> sa(v);
sa.Build();
auto sorted_indexes = sa.GetSortedIndexes();
int ans = 0;
for (int i = 0; i < n - k + 1; i++) {
ans = max(ans, sa.GetLongestCommonPrefix(sorted_indexes[i],
sorted_indexes[i + k - 1]));
}
cout << ans << '\n';
return 0;
}