forked from indy256/codelibrary
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsuffix_tree_breslauer_italiano.cpp
53 lines (45 loc) · 1.25 KB
/
suffix_tree_breslauer_italiano.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
using namespace std;
// See https://codeforces.com/blog/entry/17956?#comment-228040 for description
const int MAXLEN = 1e6;
string s;
int pos[MAXLEN], len[MAXLEN], par[MAXLEN];
unordered_map<char, int> to[MAXLEN], Link[MAXLEN];
int sz = 2;
void attach(int child, int parent, char c, int child_len) {
to[parent][c] = child;
len[child] = child_len;
par[child] = parent;
}
void extend(char c) {
int v;
int i = s.size();
int old = sz - 1;
for (v = old; !Link[v].count(c); v = par[v])
i -= len[v];
int w = Link[v][c];
if (to[w].count(s[i])) {
int u = to[w][c];
for (pos[sz] = pos[u] - len[u]; s[pos[sz]] == s[i]; pos[sz] += len[v], i += len[v])
v = to[v][s[i]];
attach(sz, w, s[pos[u] - len[u]], len[u] - (pos[u] - pos[sz]));
attach(u, sz, s[pos[sz]], pos[u] - pos[sz]);
w = Link[v][c] = sz++;
}
Link[old][c] = sz;
attach(sz, w, s[i], s.size() - i);
pos[sz++] = s.size();
}
void init_tree() {
len[1] = 1;
pos[1] = 0;
par[1] = 0;
for (int c = 0; c <= 255; c++)
to[0][c] = Link[0][c] = 1;
}
int main() {
init_tree();
s = "aabababbbbadcasdf#";
for (int i = s.size() - 1; i >= 0; i--)
extend(s[i]);
}