loulett

SAIS

May 23rd, 2016
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.98 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <set>
  4. #include <vector>
  5. #include <deque>
  6. #include <algorithm>
  7. #include <numeric>
  8.  
  9. struct Stroka {
  10.     std::vector<int> str;
  11.     int start;
  12.     int same = -1;
  13. };
  14.  
  15. class SAIS {
  16. public:
  17.     SAIS::SAIS(std::vector<int> str) : str(str) {}
  18.     std::vector<int> GetSA();
  19. private:
  20.     std::vector<int> str;
  21.     std::vector<int> type;
  22.     std::vector<int> sstar;
  23.     std::set<int> alphabet;
  24.     std::vector<Stroka> sort;
  25.     std::vector<std::vector<int>> star;
  26.     std::vector<std::deque<int>> minus;
  27.     std::vector<std::deque<int>> plus;
  28.     int alph_size;
  29.  
  30.     void getAlphabetSize();
  31.     std::vector<int> sufMas();
  32.     void setType();
  33.     void radixSort(int l, int r, int j);
  34.     void sortMinus();
  35.     void sortPlus();
  36. };
  37.  
  38. int maxChar = -1;
  39.  
  40. void SAIS::radixSort(int l, int r, int j) {
  41.     if (r - l < 1) {
  42.         return;
  43.     }
  44.     if (r - l == 1) {
  45.         maxChar++;
  46.         sort[l].same = maxChar;
  47.         return;
  48.     }
  49.     std::vector<std::vector<Stroka>> mas(alph_size + 1);
  50.     std::vector<Stroka> shor;
  51.     for (int i = l; i < r; i++) {
  52.         if (sort[i].str.size() <= j) {
  53.             shor.push_back(sort[i]);
  54.         }
  55.         else {
  56.             mas[sort[i].str[j]].push_back(sort[i]);
  57.         }
  58.     }
  59.     int q = l;
  60.     for (int i = 0; i < shor.size(); i++) {
  61.         if (i == 0)
  62.             maxChar++;
  63.         sort[q] = shor[i];
  64.         sort[q].same = maxChar;
  65.         q++;
  66.     }
  67.     for (int i = 0; i < alph_size + 1; i++) {
  68.         for (int k = 0; k < mas[i].size(); k++) {
  69.             sort[q] = mas[i][k];
  70.             q++;
  71.         }
  72.         radixSort(q - mas[i].size(), q, j + 1);
  73.     }
  74. }
  75.  
  76. void SAIS::getAlphabetSize() {
  77.     for (int i = 0; i < str.size(); i++) {
  78.         alphabet.insert(str[i]);
  79.     }
  80. }
  81.  
  82. std::vector<int> SAIS::sufMas() {
  83.     std::vector<std::vector<int>> buckets(alph_size);
  84.     for (int i = 0; i < str.size(); i++) {
  85.         buckets[str[i]].push_back(i);
  86.     }
  87.     std::vector<int> sufmas;
  88.     for (int i = 0; i < alph_size; i++) {
  89.         for (int j = 0; j < buckets[i].size(); j++) {
  90.             sufmas.push_back(buckets[i][j]);
  91.         }
  92.     }
  93.     return sufmas;
  94. }
  95.  
  96. void SAIS::setType() {
  97.     type[str.size() - 1] = 2;
  98.     sstar.push_back(str.size() - 1);
  99.     for (int i = str.size() - 2; i >= 0; i--) {
  100.         if (str[i] < str[i + 1])
  101.             type[i] = 1;
  102.         else if (str[i] > str[i + 1])
  103.             type[i] = 0;
  104.         else if (type[i + 1] == 0)
  105.             type[i] = 0;
  106.         else
  107.             type[i] = 1;
  108.  
  109.         if (type[i + 1] == 1 && type[i] == 0) {
  110.             type[i + 1] = 2;
  111.             sstar.push_back(i + 1);
  112.         }
  113.     }
  114.     std::reverse(sstar.begin(), sstar.end());
  115. }
  116.  
  117. void SAIS::sortMinus() {
  118.     minus[str[str.size() - 2]].push_back(str.size() - 2);
  119.     std::deque<int> c;
  120.     for (int i = 1; i < alph_size; i++) {
  121.         c.clear();
  122.         while(!minus[i].empty()) {
  123.             int letter = minus[i][0];
  124.             minus[i].pop_front();
  125.             c.push_back(letter);
  126.             if (letter > 0 && str[letter - 1] >= i) {
  127.                 minus[str[letter - 1]].push_back(letter - 1);
  128.             }
  129.         }
  130.         minus[i] = c;
  131.         for (int j = 0; j < star[i].size(); j++) {
  132.             minus[str[star[i][j] - 1]].push_back(star[i][j] - 1);
  133.         }
  134.     }
  135.  
  136. }
  137.  
  138. void SAIS::sortPlus () {
  139.     std::deque<int> c;
  140.     for (int i = alph_size - 1; i >= 1; i--) {
  141.         c.clear();
  142.         while (!plus[i].empty()) {
  143.             int letter = plus[i].back();
  144.             plus[i].pop_back();
  145.             c.push_front(letter);
  146.             if (letter > 0 && str[letter - 1] <= i) {
  147.                 plus[str[letter - 1]].push_front(letter - 1);
  148.             }
  149.         }
  150.         plus[i] = c;
  151.         for (int j = minus[i].size() - 1; j >= 0; j--) {
  152.             if (minus[i][j] - 1 >= 0 && str[minus[i][j] - 1] < i) {
  153.                 plus[str[minus[i][j] - 1]].push_front(minus[i][j] - 1);
  154.             }
  155.         }
  156.     }
  157. }
  158.  
  159. std::vector<int> SAIS::GetSA() {
  160.     getAlphabetSize();
  161.     auto it = alphabet.end();
  162.     it--;
  163.     alph_size = *(it) + 1;
  164.     if (alphabet.size() == str.size()) {
  165.         return sufMas();
  166.     }
  167.     type.resize(str.size());
  168.     setType();
  169.     sort.resize(sstar.size());
  170.     for (int i = 0; i < sstar.size() - 1; i++) {
  171.         sort[i].start = sstar[i];
  172.         for (int j = sstar[i]; j <= sstar[i + 1]; j++) {
  173.             sort[i].str.push_back(str[j]);
  174.         }
  175.         sort[i].str.push_back(alph_size);
  176.     }
  177.     sort.back().start = sstar.back();
  178.     sort.back().str = { 0 };
  179.     maxChar = -1;
  180.     radixSort(0, sort.size(), 0);
  181.     std::vector<int> help(str.size(), -1);
  182.     std::vector<int> help1(str.size(), -1);
  183.     for (int i = 0; i < sort.size(); i++) {
  184.         help[sort[i].start] = sort[i].same;
  185.         help1[sort[i].start] = i;
  186.     }
  187.     std::vector<int> new_str;
  188.     std::vector<int> new_str1;
  189.     for (int i = 0; i < str.size(); i++) {
  190.         if (help[i] > -1) {
  191.             new_str.push_back(help[i]);
  192.             new_str1.push_back(help1[i]);
  193.         }
  194.     }
  195.     SAIS a(new_str);
  196.     std::vector<int> suffmas1 = a.GetSA();
  197.     star.resize(alph_size);
  198.     for (int i = 0; i < suffmas1.size(); i++) {
  199.         star[sort[new_str1[suffmas1[i]]].str[0]].push_back(sort[new_str1[suffmas1[i]]].start);
  200.     }
  201.     minus.resize(alph_size);
  202.     plus.resize(alph_size);
  203.     sortMinus();
  204.     sortPlus();
  205.     std::vector<int> sufmas = { static_cast<int>(str.size() - 1) };
  206.     for (int i = 1; i < alph_size; i++) {
  207.         sufmas.insert(sufmas.end(), minus[i].begin(), minus[i].end());
  208.         sufmas.insert(sufmas.end(), plus[i].begin(), plus[i].end());
  209.     }
  210.     return sufmas;
  211. }
  212.  
  213. void kasai(std::vector<int>& str, std::vector<int>& sufmas, std::vector<int>& lcp) {
  214.     int n = str.size();
  215.     std::vector<int> pos(n);
  216.     for (int i = 0; i < n; i++) {
  217.         pos[sufmas[i]] = i;
  218.     }
  219.     int k = 0;
  220.     for (int i = 0; i < n; i++) {
  221.         if (k > 0) {
  222.             k--;
  223.         }
  224.         if (pos[i] == n - 1) {
  225.             lcp[n - 1] = -1;
  226.             k = 0;
  227.         }
  228.         else {
  229.             int j = sufmas[pos[i] + 1];
  230.             while (std::max(i + k, j + k) < n && str[i + k] == str[j + k])
  231.                 k++;
  232.             lcp[pos[i]] = k;
  233.         }
  234.     }
  235. }
  236.  
  237. int main() {
  238.     int k = 0;
  239.     std::cin >> k;
  240.     std::vector<int> str;
  241.     std::string str1;
  242.     std::cin >> str1;
  243.     int n = str1.length();
  244.     while (str1.length() < n + k) {
  245.         str1 += str1;
  246.     }
  247.     for (int j = 0; j < n; j++) {
  248.         std::string str2 = str1.substr(j, k);
  249.         str.clear();
  250.         for (int i = 0; i < str2.size(); i++)
  251.         {
  252.             str.push_back(str2[i] - 'a' + 1);
  253.         }
  254.         str.push_back(0);
  255.         SAIS a(str);
  256.         std::vector<int> sufmas = a.GetSA();
  257.         std::vector<int> lcp(str.size());
  258.         kasai(str, sufmas, lcp);
  259.         int ans = (str.size())*(str.size() - 1) / 2;
  260.         ans -= std::accumulate(lcp.begin(), lcp.end(), 0) + 1;
  261.         std::cout << ans << ' ';
  262.     }
  263.     return 0;
  264. }
Advertisement
Add Comment
Please, Sign In to add comment