Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <utility>
- typedef std::vector<int>::iterator Iterator;
- typedef std::vector<std::pair<int, int>>::iterator pIt;
- class SuffixArray{
- public:
- SuffixArray(const std::string& _text);
- std::vector<int> GetSuffArray();
- void Print();
- private:
- std::vector<std::pair<int, int>> suff_array;
- std::string text;
- int text_len;
- std::vector<int> cls;
- void ZeroStepSort();
- void ExpandArray(int deg);
- };
- std::vector<int> SuffixArray::GetSuffArray() {
- std::vector<int> suff(text_len);
- for (size_t i = 0; i < text_len; ++i) {
- suff[i] = suff_array[i].second;
- }
- return suff;
- }
- void SuffixArray::ZeroStepSort() {
- std::vector<std::pair<char, int>> indexed_text(text_len);
- for (int i = 0; i < text_len; ++i) {
- indexed_text[i] = std::make_pair(text[i], i);
- }
- std::sort(indexed_text.begin(), indexed_text.end());
- int cls_cnt = 0;
- char prev_letter = indexed_text[0].first;
- for (auto leter : indexed_text) {
- suff_array.push_back({(leter.first > prev_letter? ++cls_cnt : cls_cnt), leter.second});
- cls[leter.second] = cls_cnt;
- prev_letter = leter.first;
- }
- }
- void SuffixArray::ExpandArray(int deg) {
- for (int i = 0; i < text_len; ++i) {
- int index = (text_len + (suff_array[i].second - (1 << deg))) % text_len;
- suff_array[i] = std::make_pair(cls[index], index);
- }
- }
- SuffixArray::SuffixArray(const std::string& _text) : text(_text + char(0)),
- text_len(static_cast<int>(_text.size()) + 1),
- cls(_text.size() + 1, 0) {
- suff_array.reserve(text_len);
- ZeroStepSort();
- std::vector<int> cls_cnt(text_len, 0);
- std::vector<std::pair<int, int>> _suff_array(text_len);
- for (int deg = 0; (1 << deg) < text_len; ++deg) {
- cls_cnt.assign(text_len, 0);
- ExpandArray(deg);
- for (auto suff : suff_array) {
- ++cls_cnt[suff.first];
- }
- for (int i = 1; i < text_len; ++i) {
- cls_cnt[i] += cls_cnt[i - 1];
- }
- for (int i = text_len - 1; i >= 0; --i) {
- _suff_array[--cls_cnt[suff_array[i].first]] = suff_array[i];
- }
- suff_array = _suff_array;
- cls_cnt = cls;
- int counter = 0;
- cls[0] = 0;
- suff_array[0].first = 0;
- for (size_t i = 1; i < text_len; ++i) {
- size_t l = (suff_array[i - 1].second + (1 << deg)) % text_len;
- size_t r = (suff_array[i].second + (1 << deg)) % text_len;
- if (cls_cnt[suff_array[i - 1].second] < cls_cnt[suff_array[i].second] ||
- cls_cnt[l] < cls_cnt[r]) {
- ++counter;
- }
- suff_array[i].first = counter;
- cls[suff_array[i].second] = counter;
- }
- }
- }
- void SuffixArray::Print() {
- for (auto suf : suff_array) {
- std::cout << std::string(text.begin() + suf.second, text.end());
- std::cout << std::endl;
- }
- }
- void BuildLCP(const std::vector<int>& suf,
- const std::string& s,
- std::vector<int>& lcp) {
- size_t n = s.size();
- std::vector<int> opposite_suf(n);
- for (int i = 0; i < n; ++i) {
- opposite_suf[suf[i]] = i;
- }
- int k = 0;
- for (int i = 0; i < n; ++i) {
- if (k) {
- --k;
- }
- if (opposite_suf[i] == n - 1) {
- lcp[n - 1] = -1;
- k = 0;
- }
- else {
- int j = suf[opposite_suf[i] + 1];
- while (std::max(i + k, j + k) < n && s[i + k] == s[j + k]) {
- ++k;
- }
- lcp[opposite_suf[i]] = k;
- }
- }
- }
- void Solve() {
- std::string s;
- std::string t;
- int t_size = static_cast<int>(t.size());
- int k = 0;
- std::cin >> s >> t >> k;
- int s_size = static_cast<int>(s.size());
- s += "!" + t ;
- SuffixArray suff(s);
- std::vector<int> suffix_array = suff.GetSuffArray();
- std::vector<int> lcp(s.size() + 1, 0);
- BuildLCP(suffix_array, s+char(0), lcp);
- std::string result;
- size_t count = 0;
- int min_lcp = 0;
- for (size_t i = 3; i <= s.size(); ++i) {
- if ((suffix_array[i] <= s_size && suffix_array[i - 1] > s_size) ||
- (suffix_array[i] > s_size && suffix_array[i - 1] <= s_size)) {
- min_lcp = std::min(lcp[i - 1], min_lcp);
- if (count + lcp[i - 1] - min_lcp >= k) {
- if (suffix_array[i] <= s_size) {
- --i;
- }
- std::string::iterator start = t.begin() + suffix_array[i] - (s_size + 1);
- std::string::iterator end = start + min_lcp + k - count;
- std::cout << std::string(start, end);
- return;
- }
- else {
- count += lcp[i - 1] - min_lcp;
- }
- min_lcp = lcp[i - 1];
- }
- }
- std::cout << -1 << std::endl;
- }
- int main() {
- Solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment