1
1
/*
2
2
3
- The idea of using Treap data structure for storing the transitions
3
+ The idea of using Treap data structure for storing the transitions
4
4
in every Node of the automaton is thanks to Iliyan Yordanov Yordanov
5
5
6
6
The construction time complexity of the automaton is guaranteed O(n*log(Sigma)),
@@ -32,7 +32,7 @@ struct Node {
32
32
}
33
33
};
34
34
35
- int numNodes ;
35
+ int num_nodes ;
36
36
37
37
struct Treap {
38
38
private:
@@ -42,6 +42,7 @@ struct Treap {
42
42
if (t == -1 ) {
43
43
return void (l = r = -1 );
44
44
}
45
+
45
46
if (nodes[t].key < key) {
46
47
split (nodes[t].r , nodes[t].r , r, key), l = t;
47
48
} else {
@@ -53,6 +54,7 @@ struct Treap {
53
54
if (l == -1 || r == -1 ) {
54
55
return void (t = (l == -1 ? r : l));
55
56
}
57
+
56
58
if (nodes[l].prior < nodes[r].prior ) {
57
59
merge (nodes[r].l , l, nodes[r].l ), t = r;
58
60
} else {
@@ -63,9 +65,10 @@ struct Treap {
63
65
public:
64
66
inline void insert (int &t, char key, int state) {
65
67
int l, m, r;
68
+
66
69
split (t, l, r, key);
67
70
68
- m = numNodes ++;
71
+ m = num_nodes ++;
69
72
nodes[m].set (key, state);
70
73
71
74
merge (t, l, m);
@@ -74,11 +77,13 @@ struct Treap {
74
77
75
78
inline void copy (int &cur, int &other) {
76
79
if (other != -1 ) {
77
- cur = numNodes ++;
80
+ cur = num_nodes ++;
78
81
nodes[cur] = nodes[other];
82
+
79
83
if (nodes[other].l != -1 ) {
80
84
copy (nodes[cur].l , nodes[other].l );
81
85
}
86
+
82
87
if (nodes[other].r != -1 ) {
83
88
copy (nodes[cur].r , nodes[other].r );
84
89
}
@@ -98,7 +103,7 @@ struct Treap {
98
103
}
99
104
}
100
105
101
- inline vector<Node> &getTreapNodes () {
106
+ inline vector<Node> &get_treap_nodes () {
102
107
return this ->nodes ;
103
108
};
104
109
@@ -117,112 +122,137 @@ struct State {
117
122
118
123
vector<State> states;
119
124
vector<int > transitions;
120
- int numInfix ;
125
+ int num_infix ;
121
126
122
- int prefixState (0 ), last(0 );
127
+ int prefix_state (0 ), last(0 );
123
128
124
129
inline void add (char symbol) {
125
- int nq = ++prefixState ; // the guaranteed new prefix state
130
+ int nq = ++prefix_state ; // the guaranteed new prefix state
126
131
states[nq].set (states[last].len + 1 , -1 , nq);
127
132
transitions[nq] = -1 ;
128
- int currTransition, q;
133
+
134
+ int curr_transition, q;
129
135
q = last;
136
+
130
137
while (q != -1 ) { // traverse upwards to root
131
- currTransition = T.find (transitions[q], symbol);
132
- if (currTransition != -1 ) {
138
+ curr_transition = T.find (transitions[q], symbol);
139
+
140
+ if (curr_transition != -1 ) {
133
141
break ;
134
142
}
135
143
T.insert (transitions[q], symbol, nq);
136
144
q = states[q].par ;
137
145
}
146
+
138
147
last = nq;
148
+
139
149
if (q == -1 ) {
140
150
return void (states[nq].par = 0 );
141
151
}
142
- int p = T.getTreapNodes ()[currTransition].state ;
152
+
153
+ int p = T.get_treap_nodes ()[curr_transition].state ;
154
+
143
155
if (states[q].len + 1 == states[p].len ) {
144
156
return void (states[nq].par = p);
145
157
}
146
158
147
- int clone = numInfix++;
159
+ int clone = num_infix++;
160
+
148
161
states[clone].set (states[q].len + 1 , states[p].par , states[p].fir );
149
162
transitions[clone] = -1 ;
150
163
T.copy (transitions[clone], transitions[p]);
164
+
151
165
while (q != -1 ) {
152
- currTransition = T.find (transitions[q], symbol);
153
- if (T.getTreapNodes ()[currTransition].state != p) {
166
+ curr_transition = T.find (transitions[q], symbol);
167
+
168
+ if (T.get_treap_nodes ()[curr_transition].state != p) {
154
169
break ;
155
170
}
156
- T.getTreapNodes ()[currTransition].state = clone;
171
+
172
+ T.get_treap_nodes ()[curr_transition].state = clone;
157
173
q = states[q].par ;
158
174
}
159
175
states[p].par = states[nq].par = clone;
160
176
}
161
177
162
- vector<int > prevEdge ;
163
- int cntEdges ;
178
+ vector<int > prev_edge ;
179
+ int cnt_edges ;
164
180
165
- void addEdge (int from, int to = cntEdges ) { // to is always equal to cntEdges
166
- prevEdge [to] = transitions[from];
167
- transitions[from] = cntEdges ++;
181
+ void add_edge (int from, int to = cnt_edges ) { // to is always equal to cnt_edges
182
+ prev_edge [to] = transitions[from];
183
+ transitions[from] = cnt_edges ++;
168
184
}
169
185
170
186
vector<int > in, out;
171
187
int t;
172
188
173
189
void dfs (int v) {
174
190
in[v] = t++;
175
- for (int to = transitions[v]; to; to = prevEdge[to]) {
191
+
192
+ for (int to = transitions[v]; to; to = prev_edge[to]) {
176
193
dfs (to);
177
194
}
195
+
178
196
out[v] = t++;
179
197
}
180
198
181
- int cntSquares;
182
- vector<int > lenState;
199
+ int cnt_squares;
200
+ vector<int > len_state;
201
+
202
+ void find_squares (int ver) {
203
+ len_state[states[ver].len ] = ver;
204
+
205
+ int half = len_state[states[ver].len >> 1 ];
183
206
184
- void findSquares (int ver) {
185
- lenState[states[ver].len ] = ver;
186
- int half = lenState[states[ver].len >> 1 ];
187
207
if ((half != -1 ) && ((states[half].len << 1 ) == states[ver].len )) {
188
208
int ind = states[ver].fir - (states[ver].len >> 1 );
209
+
189
210
if ((in[half] <= in[ind]) && (in[ind] <= out[half])) {
190
- ++cntSquares ;
211
+ ++cnt_squares ;
191
212
}
192
213
}
193
- for (int to = transitions[ver]; to; to = prevEdge[to]) {
194
- findSquares (to);
214
+
215
+ for (int to = transitions[ver]; to; to = prev_edge[to]) {
216
+ find_squares (to);
195
217
}
196
- lenState[states[ver].len ] = -1 ;
218
+
219
+ len_state[states[ver].len ] = -1 ;
197
220
}
198
221
199
222
void init (int n) {
200
223
states.resize (2 * n);
201
- T.getTreapNodes ().resize (3 * n);
202
- numNodes = 0 ;
224
+ T.get_treap_nodes ().resize (3 * n);
225
+ num_nodes = 0 ;
226
+
203
227
transitions.resize (2 * n);
204
228
}
205
229
206
230
int main (int argc, char **argv) {
207
231
if (argc != 2 ) {
208
232
printf (" Invalid executable file call! Usage: %s <file.txt>\n " , argv[0 ]);
233
+
209
234
return 1 ;
210
235
}
211
- char *filePath = argv[1 ];
212
- if (access (filePath, F_OK) < 0 || access (filePath, R_OK) < 0 ) {
236
+
237
+ char *file_path = argv[1 ];
238
+
239
+ if (access (file_path, F_OK) < 0 || access (file_path, R_OK) < 0 ) {
213
240
printf (" Provided file does not exist or is not readable.\n " );
214
241
return 2 ;
215
242
}
216
- ifstream file (filePath, ios::binary); // treat as a binary file
243
+
244
+ ifstream file (file_path, ios::binary); // treat as a binary file
217
245
file.seekg (-1 , ios::end); // seek cursor to end of file with offset -1
246
+
218
247
int n = file.tellg (); // get length of file
248
+
219
249
file.seekg (0 , ios::beg); // seek back to beginning
220
250
221
251
init (n);
222
252
223
253
states[0 ].set (0 , -1 , 0 );
224
254
transitions[0 ] = -1 ;
225
- numInfix = n + 1 ;
255
+ num_infix = n + 1 ;
226
256
last = 0 ;
227
257
228
258
char c;
@@ -231,35 +261,45 @@ int main(int argc, char **argv) {
231
261
while (file.get (c) && isalpha (c)) {
232
262
add (c);
233
263
}
264
+
234
265
file.close ();
235
266
236
- int i, cntFinal = 0 , curr = last;
267
+ int cnt_final = 0 ;
268
+ int curr = last;
269
+
237
270
while (curr != -1 ) {
238
- ++cntFinal ;
271
+ ++cnt_final ;
239
272
curr = states[curr].par ;
240
273
}
241
274
242
- prevEdge.resize (numInfix);
243
- for (i = 0 ; i < numInfix; ++i) {
275
+ prev_edge.resize (num_infix);
276
+
277
+ for (int i = 0 ; i < num_infix; ++i) {
244
278
transitions[i] = 0 ;
245
279
}
246
- cntEdges = 1 ;
247
- for (i = 1 ; i < numInfix; ++i) {
248
- addEdge (states[i].par , i);
280
+
281
+ cnt_edges = 1 ;
282
+
283
+ for (int i = 1 ; i < num_infix; ++i) {
284
+ add_edge (states[i].par , i);
249
285
}
250
286
251
- in.resize (numInfix );
252
- out.resize (numInfix );
287
+ in.resize (num_infix );
288
+ out.resize (num_infix );
253
289
254
290
t = 1 ;
255
291
dfs (0 );
256
292
257
- lenState.resize (n + 1 );
258
- for (i = 0 ; i < n; ++i) {
259
- lenState[i] = -1 ;
293
+ len_state.resize (n + 1 );
294
+
295
+ for (int i = 0 ; i < n; ++i) {
296
+ len_state[i] = -1 ;
260
297
}
261
298
262
- cntSquares = 0 ;
263
- findSquares (0 );
264
- return printf (" %d %d %d %d\n " , numInfix, numNodes, cntFinal, cntSquares), 0 ;
299
+ cnt_squares = 0 ;
300
+ find_squares (0 );
301
+
302
+ printf (" %d %d %d %d\n " , num_infix, num_nodes, cnt_final, cnt_squares);
303
+
304
+ return 0 ;
265
305
}
0 commit comments