Advertisement
Guest User

Untitled

a guest
Apr 5th, 2020
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.42 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <unordered_map>
  4. #include <vector>
  5.  
  6. struct node {
  7.   int32_t left;
  8.   int32_t right;
  9.   int32_t parent;
  10.   int32_t suff_link;
  11.   std::unordered_map<char, int32_t> next;
  12.  
  13.   node(int32_t l = 0, int32_t r = 0, int32_t p = -1) noexcept
  14.       : left{l}, right{r}, parent{p}, suff_link{-1} {}
  15.   [[nodiscard]] int32_t length() const noexcept { return right - left; }
  16.  
  17.   int32_t &get_by_char(char c) {
  18.     if (!next.count(c)) {
  19.       next[c] = -1;
  20.     }
  21.     return next[c];
  22.   }
  23. };
  24.  
  25. struct state {
  26.   int32_t vertex;
  27.   int32_t pos;
  28.   state(int32_t v, int32_t pos) : vertex{v}, pos{pos} {}
  29. };
  30.  
  31. class suff_tree {
  32.  public:
  33.   suff_tree(std::string str)
  34.       : data{std::move(str)},
  35.         nodes(data.length() * 2 + 1),
  36.         sz{1},
  37.         current_ptr{0, 0} {
  38.     for (int32_t i = 0; i < static_cast<int32_t>(data.length()); ++i) {
  39.       add_char(i);
  40.     }
  41.   }
  42.  
  43.   void print() {
  44.     std::cout << sz << ' ' << sz - 1 << '\n';
  45.     for (size_t i = 1; i < sz; ++i) {
  46.       std::cout << nodes[i].parent + 1 << ' ' << i + 1 << ' '
  47.                 << nodes[i].left + 1 << ' ' << nodes[i].right << '\n';
  48.     }
  49.   }
  50.  
  51.   struct refren_data {
  52.     std::string_view refren;
  53.     uintmax_t max_rerfen;
  54.     uintmax_t amount_of_leaves;
  55.   };
  56.   refren_data refren(size_t node = 0, uintmax_t length = 0) {}
  57.  
  58.  private:
  59.   [[nodiscard]] state go(state st, int32_t left, int32_t right) noexcept {
  60.     while (left < right)
  61.       if (st.pos == nodes[static_cast<size_t>(st.vertex)].length()) {
  62.         st = state(nodes[static_cast<size_t>(st.vertex)].get_by_char(
  63.                        data[static_cast<size_t>(left)]),
  64.                    0);
  65.         if (st.vertex == -1) {
  66.           return st;
  67.         }
  68.       } else {
  69.         if (data[static_cast<size_t>(
  70.                 nodes[static_cast<size_t>(st.vertex)].left + st.pos)] !=
  71.             data[static_cast<size_t>(left)]) {
  72.           return state(-1, -1);
  73.         }
  74.         if (right - left <
  75.             nodes[static_cast<size_t>(st.vertex)].length() - st.pos) {
  76.           return state(st.vertex, st.pos + right - left);
  77.         }
  78.         left += nodes[static_cast<size_t>(st.vertex)].length() - st.pos;
  79.         st.pos = nodes[static_cast<size_t>(st.vertex)].length();
  80.       }
  81.     return st;
  82.   }
  83.  
  84.   [[nodiscard]] int32_t split(state st) noexcept {
  85.     if (st.pos == nodes[static_cast<size_t>(st.vertex)].length()) {
  86.       return st.vertex;
  87.     }
  88.     if (st.pos == 0) {
  89.       return nodes[static_cast<size_t>(st.vertex)].parent;
  90.     }
  91.     node v = nodes[static_cast<size_t>(st.vertex)];
  92.     size_t id = sz++;
  93.     nodes[id] = node(v.left, v.left + st.pos, v.parent);
  94.     nodes[static_cast<size_t>(v.parent)].get_by_char(
  95.         data[static_cast<size_t>(v.left)]) = static_cast<int32_t>(id);
  96.     nodes[id].get_by_char(data[static_cast<size_t>(v.left + st.pos)]) =
  97.         st.vertex;
  98.     nodes[static_cast<size_t>(st.vertex)].parent = static_cast<int32_t>(id);
  99.     nodes[static_cast<size_t>(st.vertex)].left += st.pos;
  100.     return static_cast<int32_t>(id);
  101.   }
  102.  
  103.   [[nodiscard]] int32_t get_suff_link(size_t v) noexcept {
  104.     if (nodes[v].suff_link != -1) {
  105.       return nodes[v].suff_link;
  106.     }
  107.     if (nodes[v].parent == -1) {
  108.       return 0;
  109.     }
  110.     int32_t to = get_suff_link(static_cast<size_t>(nodes[v].parent));
  111.     return nodes[v].suff_link = split(
  112.                go(state(to, static_cast<int32_t>(
  113.                                 nodes[static_cast<size_t>(to)].length())),
  114.                   nodes[v].left + (nodes[v].parent == 0), nodes[v].right));
  115.   }
  116.  
  117.   void add_char(int32_t pos) noexcept {
  118.     while (true) {
  119.       state nptr = go(current_ptr, pos, pos + 1);
  120.       if (nptr.vertex != -1) {
  121.         current_ptr = nptr;
  122.         return;
  123.       }
  124.  
  125.       size_t mid = static_cast<size_t>(split(current_ptr));
  126.       size_t leaf = sz++;
  127.       nodes[leaf] = node(pos, static_cast<int32_t>(data.length()),
  128.                          static_cast<int32_t>(mid));
  129.       nodes[mid].get_by_char(data[static_cast<size_t>(pos)]) =
  130.           static_cast<int32_t>(leaf);
  131.  
  132.       current_ptr.vertex = get_suff_link(mid);
  133.       current_ptr.pos = nodes[static_cast<size_t>(current_ptr.vertex)].length();
  134.       if (!mid) {
  135.         break;
  136.       }
  137.     }
  138.   }
  139.   std::string data;
  140.   std::vector<node> nodes;
  141.   size_t sz;
  142.   state current_ptr;
  143. };
  144.  
  145. int main() {
  146.   std::string text;
  147.   std::cin >> text;
  148.   suff_tree tree(text);
  149.   tree.print();
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement