-
Notifications
You must be signed in to change notification settings - Fork 77
/
suffix_automata.cpp
94 lines (83 loc) · 2.36 KB
/
suffix_automata.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#define maxN 250005
#define maxState (maxN << 1)
#define ASCII 128
// Necessary to calculate longest common substring in linear time where suffix array yields TLE
struct State {
State *next[ASCII]; // //Links to next transition state in the DAWG (Directed acyclic word graph)
State *suffix; // //Link to previous transition state in the DAWG
int depth, id;
// long long cnt;
};
State pool[maxState]; // pool of states, from where you can pick a raw state to include in the DAWG
State *point, *root, *sink;
int size; // number of states present in the DAWG.
State *newState(int dep) {
point->id = size++;
point->depth = dep;
return point++;
}
void init() {
point = pool;
size = 0;
root = sink = newState(0);
}
void extend(int a) {
State *p = newState(sink->depth + 1);
State *cur = sink, *sufState;
while (cur and !cur->next[a]) {
cur->next[a] = p;
cur = cur->suffix;
}
if (!cur)
sufState = root;
else {
State *q = cur->next[a];
if (q->depth == cur->depth + 1)
sufState = q;
else {
State *r = newState(cur->depth+1);
memcpy(r->next, q->next, sizeof(q->next));
r->suffix = q->suffix;
q->suffix = r;
sufState = r;
while (cur and cur->next[a] == q) {
cur->next[a] = r;
cur = cur->suffix;
}
}
}
p->suffix = sufState;
sink = p;
}
int LCSubstr(string const& S1, string const& S2) {
init();
int len = (int)S1.length();
for (int i = 0; i < len; i++)
extend(S1[i]-'a');
len = (int)S2.length();
int indx = 0, length = 0, Max = 0;
State *cur = root;
for (int i = 0; i < len; i++) {
if (cur->next[S2[i] - 'a']) {
length++;
cur = cur->next[S2[i] - 'a'];
} else {
while (cur and !cur->next[S2[i] - 'a'])
cur = cur->suffix;
if (!cur) {
cur = root;
length = 0;
} else {
length = cur->depth + 1;
cur = cur->next[S2[i] - 'a'];
}
}
if(length > Max) {
Max = length;
indx = i - length + 1;
}
}
if(Max > 0)
pf("%s\n", S2.substr(indx, Max).c_str());
return Max; // len
}