Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <map>
- #include <string>
- #include <vector>
- using namespace std;
- const int MXn = 1000000;
- struct ver {
- int l, r, pP, lk, dser;
- map<char, int> next;
- ver(int l = 0, int r = 0, int pP = -1)
- : l(l), r(r), pP(pP), lk(-1) {}
- int len() { return r - l; }
- int &get(char c) {
- if (!next.count(c)) next[c] = -1;
- return next[c];
- }
- };
- ver t[MXn];
- int size_;
- struct stt {
- int v, pos;
- stt(int v, int pos) : v(v), pos(pos) {}
- };
- stt ptr(0, 0);
- stt go(stt st, int l, int r, string& s) {
- while (l < r)
- if (st.pos == t[st.v].len()) {
- st = stt(t[st.v].get(s[l]), 0);
- if (st.v == -1) return st;
- }
- else {
- if (s[t[st.v].l + st.pos] != s[l])
- return stt(-1, -1);
- if (r - l < t[st.v].len() - st.pos)
- return stt(st.v, st.pos + r - l);
- l += t[st.v].len() - st.pos;
- st.pos = t[st.v].len();
- }
- return st;
- }
- int split(stt st, string& s) {
- if (st.pos == t[st.v].len())
- return st.v;
- if (st.pos == 0)
- return t[st.v].pP;
- ver v = t[st.v];
- int id = size_++;
- t[id] = ver(v.l, v.l + st.pos, v.pP);
- t[v.pP].get(s[v.l]) = id;
- t[id].get(s[v.l + st.pos]) = st.v;
- t[st.v].pP = id;
- t[st.v].l += st.pos;
- return id;
- }
- int get_lk(int v, string& s) {
- if (t[v].lk != -1) return t[v].lk;
- if (t[v].pP == -1) return 0;
- int to = get_lk(t[v].pP, s);
- return t[v].lk = split(go(stt(to, t[to].len()), t[v].l + (t[v].pP == 0), t[v].r, s), s);
- }
- void tree_extend(string& s, int pos) {
- for (;;) {
- stt nptr = go(ptr, pos, pos + 1, s);
- if (nptr.v != -1) {
- ptr = nptr;
- return;
- }
- int sered = split(ptr, s);
- int last = size_++;
- t[last] = ver(pos, s.length(), sered);
- t[sered].get(s[pos]) = last;
- ptr.v = get_lk(sered, s);
- ptr.pos = t[ptr.v].len();
- if (!sered) break;
- }
- }
- void set_dser(int idx, int& dser)
- {
- t[idx].dser = dser;
- if (t[idx].next.size() > 0)
- {
- for (map<char, int>::iterator it = t[idx].next.begin(), it_end = t[idx].next.end(); it != it_end; it++)
- {
- dser++;
- set_dser(it->second, dser);
- }
- }
- }
- void print_subtree(int idx)
- {
- cout << t[idx].pP << ' ' << t[idx].l << ' ' << t[idx].r << endl;
- for (map<char, int>::iterator it = t[idx].next.begin(), it_end = t[idx].next.end(); it != it_end; it++)
- print_subtree(it->second);
- }
- void print_tree()
- {
- cout << size_ << endl;
- for (map<char, int>::iterator it = t[0].next.begin(), it_end = t[0].next.end(); it != it_end; it++)
- print_subtree(it->second);
- }
- int main()
- {
- string s;
- cin >> s;
- size_ = 1;
- for (int i = 0; i < s.length(); ++i)
- tree_extend(s, i);
- int dser = 0;
- vector<map<char, int>::iterator> v;
- int idx = 0;
- map<char, int>::iterator it;
- bool flag = true;
- while (1)
- {
- if (flag)
- {
- t[idx].dser = dser;
- dser++;
- it = t[idx].next.begin();
- }
- if (it != t[idx].next.end())
- {
- flag = true;
- v.push_back(it);
- idx = it->second;
- }
- else
- {
- if (v.size() == 0)
- break;
- it = v.back();
- v.pop_back();
- it++;
- flag = false;
- idx = t[idx].pP;
- }
- }
- idx = 0;
- flag = true;
- cout << size_ << endl;
- while (1)
- {
- if (flag)
- {
- if (idx)
- cout << t[t[idx].pP].dser << ' ' << t[idx].l << ' ' << t[idx].r << endl;
- it = t[idx].next.begin();
- }
- if (it != t[idx].next.end())
- {
- flag = true;
- v.push_back(it);
- idx = it->second;
- }
- else
- {
- if (v.size() == 0)
- break;
- it = v.back();
- v.pop_back();
- it++;
- flag = false;
- idx = t[idx].pP;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement