Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <unordered_map>
- #include <vector>
- struct node {
- int32_t left;
- int32_t right;
- int32_t parent;
- int32_t suff_link;
- std::unordered_map<char, int32_t> next;
- node(int32_t l = 0, int32_t r = 0, int32_t p = -1) noexcept
- : left{l}, right{r}, parent{p}, suff_link{-1} {}
- [[nodiscard]] int32_t length() const noexcept { return right - left; }
- int32_t &get_by_char(char c) {
- if (!next.count(c)) {
- next[c] = -1;
- }
- return next[c];
- }
- };
- struct state {
- int32_t vertex;
- int32_t pos;
- state(int32_t v, int32_t pos) : vertex{v}, pos{pos} {}
- };
- class suff_tree {
- public:
- suff_tree(std::string str)
- : data{std::move(str)},
- nodes(data.length() * 2 + 1),
- sz{1},
- current_ptr{0, 0} {
- for (int32_t i = 0; i < static_cast<int32_t>(data.length()); ++i) {
- add_char(i);
- }
- }
- void print() {
- std::cout << sz << ' ' << sz - 1 << '\n';
- for (size_t i = 1; i < sz; ++i) {
- std::cout << nodes[i].parent + 1 << ' ' << i + 1 << ' '
- << nodes[i].left + 1 << ' ' << nodes[i].right << '\n';
- }
- }
- struct refren_data {
- std::string_view refren;
- uintmax_t max_rerfen;
- uintmax_t amount_of_leaves;
- };
- refren_data refren(size_t node = 0, uintmax_t length = 0) {}
- private:
- [[nodiscard]] state go(state st, int32_t left, int32_t right) noexcept {
- while (left < right)
- if (st.pos == nodes[static_cast<size_t>(st.vertex)].length()) {
- st = state(nodes[static_cast<size_t>(st.vertex)].get_by_char(
- data[static_cast<size_t>(left)]),
- 0);
- if (st.vertex == -1) {
- return st;
- }
- } else {
- if (data[static_cast<size_t>(
- nodes[static_cast<size_t>(st.vertex)].left + st.pos)] !=
- data[static_cast<size_t>(left)]) {
- return state(-1, -1);
- }
- if (right - left <
- nodes[static_cast<size_t>(st.vertex)].length() - st.pos) {
- return state(st.vertex, st.pos + right - left);
- }
- left += nodes[static_cast<size_t>(st.vertex)].length() - st.pos;
- st.pos = nodes[static_cast<size_t>(st.vertex)].length();
- }
- return st;
- }
- [[nodiscard]] int32_t split(state st) noexcept {
- if (st.pos == nodes[static_cast<size_t>(st.vertex)].length()) {
- return st.vertex;
- }
- if (st.pos == 0) {
- return nodes[static_cast<size_t>(st.vertex)].parent;
- }
- node v = nodes[static_cast<size_t>(st.vertex)];
- size_t id = sz++;
- nodes[id] = node(v.left, v.left + st.pos, v.parent);
- nodes[static_cast<size_t>(v.parent)].get_by_char(
- data[static_cast<size_t>(v.left)]) = static_cast<int32_t>(id);
- nodes[id].get_by_char(data[static_cast<size_t>(v.left + st.pos)]) =
- st.vertex;
- nodes[static_cast<size_t>(st.vertex)].parent = static_cast<int32_t>(id);
- nodes[static_cast<size_t>(st.vertex)].left += st.pos;
- return static_cast<int32_t>(id);
- }
- [[nodiscard]] int32_t get_suff_link(size_t v) noexcept {
- if (nodes[v].suff_link != -1) {
- return nodes[v].suff_link;
- }
- if (nodes[v].parent == -1) {
- return 0;
- }
- int32_t to = get_suff_link(static_cast<size_t>(nodes[v].parent));
- return nodes[v].suff_link = split(
- go(state(to, static_cast<int32_t>(
- nodes[static_cast<size_t>(to)].length())),
- nodes[v].left + (nodes[v].parent == 0), nodes[v].right));
- }
- void add_char(int32_t pos) noexcept {
- while (true) {
- state nptr = go(current_ptr, pos, pos + 1);
- if (nptr.vertex != -1) {
- current_ptr = nptr;
- return;
- }
- size_t mid = static_cast<size_t>(split(current_ptr));
- size_t leaf = sz++;
- nodes[leaf] = node(pos, static_cast<int32_t>(data.length()),
- static_cast<int32_t>(mid));
- nodes[mid].get_by_char(data[static_cast<size_t>(pos)]) =
- static_cast<int32_t>(leaf);
- current_ptr.vertex = get_suff_link(mid);
- current_ptr.pos = nodes[static_cast<size_t>(current_ptr.vertex)].length();
- if (!mid) {
- break;
- }
- }
- }
- std::string data;
- std::vector<node> nodes;
- size_t sz;
- state current_ptr;
- };
- int main() {
- std::string text;
- std::cin >> text;
- suff_tree tree(text);
- tree.print();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement