1
+ string s;
2
+ int n;
3
+
4
+ struct node {
5
+ int l, r, par, link;
6
+ map<char,int> next;
7
+
8
+ node (int l=0, int r=0, int par=-1)
9
+ : l(l), r(r), par(par), link(-1) {}
10
+ int len() { return r - l; }
11
+ int &get (char c) {
12
+ if (!next.count(c)) next[c] = -1;
13
+ return next[c];
14
+ }
15
+ };
16
+ node t[MAXN];
17
+ int sz;
18
+
19
+ struct state {
20
+ int v, pos;
21
+ state (int v, int pos) : v(v), pos(pos) {}
22
+ };
23
+ state ptr (0, 0);
24
+
25
+ state go (state st, int l, int r) {
26
+ while (l < r)
27
+ if (st.pos == t[st.v].len()) {
28
+ st = state (t[st.v].get( s[l] ), 0);
29
+ if (st.v == -1) return st;
30
+ }
31
+ else {
32
+ if (s[ t[st.v].l + st.pos ] != s[l])
33
+ return state (-1, -1);
34
+ if (r-l < t[st.v].len() - st.pos)
35
+ return state (st.v, st.pos + r-l);
36
+ l += t[st.v].len() - st.pos;
37
+ st.pos = t[st.v].len();
38
+ }
39
+ return st;
40
+ }
41
+
42
+ int split (state st) {
43
+ if (st.pos == t[st.v].len())
44
+ return st.v;
45
+ if (st.pos == 0)
46
+ return t[st.v].par;
47
+ node v = t[st.v];
48
+ int id = sz++;
49
+ t[id] = node (v.l, v.l+st.pos, v.par);
50
+ t[v.par].get( s[v.l] ) = id;
51
+ t[id].get( s[v.l+st.pos] ) = st.v;
52
+ t[st.v].par = id;
53
+ t[st.v].l += st.pos;
54
+ return id;
55
+ }
56
+
57
+ int get_link (int v) {
58
+ if (t[v].link != -1) return t[v].link;
59
+ if (t[v].par == -1) return 0;
60
+ int to = get_link (t[v].par);
61
+ return t[v].link = split (go (state(to,t[to].len()), t[v].l + (t[v].par==0), t[v].r));
62
+ }
63
+
64
+ void tree_extend (int pos) {
65
+ for(;;) {
66
+ state nptr = go (ptr, pos, pos+1);
67
+ if (nptr.v != -1) {
68
+ ptr = nptr;
69
+ return;
70
+ }
71
+
72
+ int mid = split (ptr);
73
+ int leaf = sz++;
74
+ t[leaf] = node (pos, n, mid);
75
+ t[mid].get( s[pos] ) = leaf;
76
+
77
+ ptr.v = get_link (mid);
78
+ ptr.pos = t[ptr.v].len();
79
+ if (!mid) break;
80
+ }
81
+ }
82
+
83
+ void build_tree() {
84
+ sz = 1;
85
+ for (int i=0; i<n; ++i)
86
+ tree_extend (i);
87
+ }
0 commit comments