anutka

Untitled

Nov 4th, 2020
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.15 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <utility>
  5.  
  6. typedef std::vector<int>::iterator Iterator;
  7. typedef std::vector<std::pair<int, int>>::iterator pIt;
  8.  
  9. class SuffixArray{
  10. public:
  11.     SuffixArray(const std::string& _text);
  12.     std::vector<int> GetSuffArray();
  13.     void Print();
  14.  
  15. private:
  16.     std::vector<std::pair<int, int>> suff_array;
  17.     std::string text;
  18.     int text_len;
  19.     std::vector<int> cls;
  20.  
  21.     void ZeroStepSort();
  22.     void ExpandArray(int deg);
  23.  
  24. };
  25.  
  26. std::vector<int> SuffixArray::GetSuffArray() {
  27.     std::vector<int> suff(text_len);
  28.     for (size_t i = 0; i < text_len; ++i) {
  29.         suff[i] = suff_array[i].second;
  30.     }
  31.     return suff;
  32. }
  33.  
  34. void SuffixArray::ZeroStepSort() {
  35.  
  36.     std::vector<std::pair<char, int>> indexed_text(text_len);
  37.  
  38.     for (int i = 0; i < text_len; ++i) {
  39.         indexed_text[i] = std::make_pair(text[i], i);
  40.     }
  41.  
  42.     std::sort(indexed_text.begin(), indexed_text.end());
  43.     int cls_cnt = 0;
  44.     char prev_letter = indexed_text[0].first;
  45.  
  46.     for (auto leter : indexed_text) {
  47.         suff_array.push_back({(leter.first > prev_letter? ++cls_cnt : cls_cnt), leter.second});
  48.         cls[leter.second] = cls_cnt;
  49.         prev_letter = leter.first;
  50.     }
  51. }
  52.  
  53. void SuffixArray::ExpandArray(int deg) {
  54.     for (int i = 0; i < text_len; ++i) {
  55.         int index = (text_len + (suff_array[i].second - (1 << deg))) % text_len;
  56.         suff_array[i] = std::make_pair(cls[index], index);
  57.     }
  58. }
  59.  
  60. SuffixArray::SuffixArray(const std::string& _text) : text(_text + char(0)),
  61.                                                      text_len(static_cast<int>(_text.size()) + 1),
  62.                                                      cls(_text.size() + 1, 0) {
  63.  
  64.     suff_array.reserve(text_len);
  65.     ZeroStepSort();
  66.     std::vector<int> cls_cnt(text_len, 0);
  67.     std::vector<std::pair<int, int>> _suff_array(text_len);
  68.  
  69.     for (int deg = 0; (1 << deg) < text_len; ++deg) {
  70.         cls_cnt.assign(text_len, 0);
  71.         ExpandArray(deg);
  72.  
  73.         for (auto suff : suff_array) {
  74.             ++cls_cnt[suff.first];
  75.         }
  76.  
  77.         for (int i = 1; i < text_len; ++i) {
  78.             cls_cnt[i] += cls_cnt[i - 1];
  79.         }
  80.  
  81.         for (int i = text_len - 1; i >= 0; --i) {
  82.             _suff_array[--cls_cnt[suff_array[i].first]] = suff_array[i];
  83.         }
  84.  
  85.         suff_array = _suff_array;
  86.         cls_cnt = cls;
  87.         int counter = 0;
  88.         cls[0] = 0;
  89.         suff_array[0].first = 0;
  90.  
  91.         for (size_t i = 1; i < text_len; ++i) {
  92.  
  93.             size_t l = (suff_array[i - 1].second + (1 << deg)) % text_len;
  94.             size_t r = (suff_array[i].second + (1 << deg)) % text_len;
  95.  
  96.             if (cls_cnt[suff_array[i - 1].second] < cls_cnt[suff_array[i].second] ||
  97.                 cls_cnt[l] < cls_cnt[r]) {
  98.                 ++counter;
  99.             }
  100.  
  101.             suff_array[i].first = counter;
  102.             cls[suff_array[i].second] = counter;
  103.         }
  104.     }
  105.  
  106. }
  107.  
  108. void SuffixArray::Print() {
  109.     for (auto suf : suff_array) {
  110.         std::cout << std::string(text.begin() + suf.second, text.end());
  111.         std::cout << std::endl;
  112.     }
  113. }
  114.  
  115. void BuildLCP(const std::vector<int>& suf,
  116.               const std::string& s,
  117.               std::vector<int>& lcp) {
  118.     size_t n = s.size();
  119.     std::vector<int> opposite_suf(n);
  120.  
  121.     for (int i = 0; i < n; ++i) {
  122.         opposite_suf[suf[i]] = i;
  123.     }
  124.  
  125.     int k = 0;
  126.  
  127.     for (int i = 0; i < n; ++i) {
  128.         if (k) {
  129.             --k;
  130.         }
  131.         if (opposite_suf[i] == n - 1) {
  132.             lcp[n - 1] = -1;
  133.             k = 0;
  134.         }
  135.         else {
  136.             int j = suf[opposite_suf[i] + 1];
  137.  
  138.             while (std::max(i + k, j + k) < n && s[i + k] == s[j + k]) {
  139.                 ++k;
  140.             }
  141.             lcp[opposite_suf[i]] = k;
  142.         }
  143.     }
  144. }
  145.  
  146. void Solve() {
  147.     std::string s;
  148.     std::string t;
  149.     int t_size = static_cast<int>(t.size());
  150.     int k = 0;
  151.     std::cin >> s >> t >> k;
  152.     int s_size = static_cast<int>(s.size());
  153.     s += "!" + t ;
  154.  
  155.     SuffixArray suff(s);
  156.     std::vector<int> suffix_array = suff.GetSuffArray();
  157.     std::vector<int> lcp(s.size() + 1, 0);
  158.     BuildLCP(suffix_array, s+char(0), lcp);
  159.  
  160.     std::string result;
  161.  
  162.     size_t count = 0;
  163.     int min_lcp = 0;
  164.     for (size_t i = 3; i <= s.size(); ++i) {
  165.  
  166.         if ((suffix_array[i] <= s_size && suffix_array[i - 1] > s_size) ||
  167.             (suffix_array[i] > s_size && suffix_array[i - 1] <= s_size)) {
  168.             min_lcp = std::min(lcp[i - 1], min_lcp);
  169.             if (count + lcp[i - 1] - min_lcp >= k) {
  170.                 if (suffix_array[i] <= s_size) {
  171.                     --i;
  172.                 }
  173.                 std::string::iterator start = t.begin() + suffix_array[i] - (s_size + 1);
  174.                 std::string::iterator end = start + min_lcp + k - count;
  175.  
  176.                 std::cout << std::string(start, end);
  177.                 return;
  178.             }
  179.             else {
  180.                 count += lcp[i - 1] - min_lcp;
  181.             }
  182.             min_lcp = lcp[i - 1];
  183.  
  184.         }
  185.  
  186.     }
  187.  
  188.     std::cout << -1 << std::endl;
  189. }
  190.  
  191. int main() {
  192.     Solve();
  193.     return 0;
  194. }
  195.  
Advertisement
Add Comment
Please, Sign In to add comment