@@ -13,7 +13,7 @@ typedef vector<int> vi;
1313#include " ../../content/strings/SuffixArray.h"
1414
1515struct VecSuffixArray {
16- vi sa, lcp;
16+ vi sa, lcp;
1717 VecSuffixArray (vi &s, int lim = 256 ) {
1818 int n = sz (s), k = 0 ;
1919 vi x (2 * n), y (2 * n), wv (n), ws (max (n, lim)), rank (n);
@@ -72,7 +72,7 @@ void test(const string& s, int alpha) {
7272
7373 if (suffixes != sa.sa ) {
7474 cout << " sa fails for " << display (s) << ' ' << alpha << endl;
75- exit ( 1 );
75+ assert (suffixes == sa. sa );
7676 }
7777
7878 rep (i,0 ,sz (s)) {
@@ -85,7 +85,7 @@ void test(const string& s, int alpha) {
8585
8686 if (lcp != sa.lcp ) {
8787 cout << " lcp fails for " << display (s) << ' ' << alpha << endl;
88- exit ( 1 );
88+ assert (lcp == sa. lcp );
8989 }
9090}
9191
@@ -94,134 +94,131 @@ namespace old {
9494typedef long long ll;
9595typedef pair<ll, int > pli;
9696void count_sort (vector<pli> &b, int bits) { // (optional)
97- // this is just 3 times faster than stl sort for N=10^6
98- int mask = (1 << bits) - 1 ;
99- for (int it = 0 ; it < 2 ; it++) {
100- int move = it * bits;
101- vector<int > q (1 << bits), w ((q).size () + 1 );
102- for (int i = 0 ; i < sz (b); i++)
103- q[(b[i].first >> move) & mask]++;
104- partial_sum (q.begin (), q.end (), w.begin () + 1 );
105- vector<pli> res (b.size ());
106- for (int i = 0 ; i < sz (b); i++)
107- res[w[(b[i].first >> move) & mask]++] = b[i];
108- swap (b, res);
109- }
97+ // this is just 3 times faster than stl sort for N=10^6
98+ int mask = (1 << bits) - 1 ;
99+ for (int it = 0 ; it < 2 ; it++) {
100+ int move = it * bits;
101+ vector<int > q (1 << bits), w ((q).size () + 1 );
102+ for (int i = 0 ; i < sz (b); i++)
103+ q[(b[i].first >> move) & mask]++;
104+ partial_sum (q.begin (), q.end (), w.begin () + 1 );
105+ vector<pli> res (b.size ());
106+ for (int i = 0 ; i < sz (b); i++)
107+ res[w[(b[i].first >> move) & mask]++] = b[i];
108+ swap (b, res);
109+ }
110110}
111111struct SuffixArray {
112- vector<int > a;
113- string s;
114- SuffixArray (const string &_s) : s(_s + ' \0 ' ) {
115- int N = sz (s);
116- vector<pli> b (N);
117- a.resize (N);
118- for (int i = 0 ; i < N; i++) {
119- b[i].first = s[i];
120- b[i].second = i;
121- }
112+ vector<int > a;
113+ string s;
114+ SuffixArray (const string &_s) : s(_s + ' \0 ' ) {
115+ int N = sz (s);
116+ vector<pli> b (N);
117+ a.resize (N);
118+ for (int i = 0 ; i < N; i++) {
119+ b[i].first = s[i];
120+ b[i].second = i;
121+ }
122122
123- int q = 8 ;
124- while ((1 << q) < N)
125- q++;
126- for (int moc = 0 ;; moc++) {
127- count_sort (b, q); // sort(all(b)) can be used as well
128- a[b[0 ].second ] = 0 ;
129- for (int i = 1 ; i < N; i++)
130- a[b[i].second ] = a[b[i - 1 ].second ] + (b[i - 1 ].first != b[i].first );
123+ int q = 8 ;
124+ while ((1 << q) < N)
125+ q++;
126+ for (int moc = 0 ;; moc++) {
127+ count_sort (b, q); // sort(all(b)) can be used as well
128+ a[b[0 ].second ] = 0 ;
129+ for (int i = 1 ; i < N; i++)
130+ a[b[i].second ] = a[b[i - 1 ].second ] + (b[i - 1 ].first != b[i].first );
131131
132- if ((1 << moc) >= N)
133- break ;
134- for (int i = 0 ; i < N; i++) {
135- b[i].first = (ll)a[i] << q;
136- if (i + (1 << moc) < N)
137- b[i].first += a[i + (1 << moc)];
138- b[i].second = i;
139- }
140- }
141- for (int i = 0 ; i < sz (a); i++)
142- a[i] = b[i].second ;
143- }
144- vector<int > lcp () {
145- // longest common prefixes: res[i] = lcp(a[i],
146- // a[i-1])
147- int n = sz (a), h = 0 ;
148- vector<int > inv (n), res (n);
149- for (int i = 0 ; i < n; i++)
150- inv[a[i]] = i;
151- for (int i = 0 ; i < n; i++)
152- if (inv[i] > 0 ) {
153- int p0 = a[inv[i] - 1 ];
154- while (s[i + h] == s[p0 + h])
155- h++;
156- res[inv[i]] = h;
157- if (h > 0 )
158- h--;
159- }
160- return res;
161- }
132+ if ((1 << moc) >= N)
133+ break ;
134+ for (int i = 0 ; i < N; i++) {
135+ b[i].first = (ll)a[i] << q;
136+ if (i + (1 << moc) < N)
137+ b[i].first += a[i + (1 << moc)];
138+ b[i].second = i;
139+ }
140+ }
141+ for (int i = 0 ; i < sz (a); i++)
142+ a[i] = b[i].second ;
143+ }
144+ vector<int > lcp () {
145+ // longest common prefixes: res[i] = lcp(a[i],
146+ // a[i-1])
147+ int n = sz (a), h = 0 ;
148+ vector<int > inv (n), res (n);
149+ for (int i = 0 ; i < n; i++)
150+ inv[a[i]] = i;
151+ for (int i = 0 ; i < n; i++)
152+ if (inv[i] > 0 ) {
153+ int p0 = a[inv[i] - 1 ];
154+ while (s[i + h] == s[p0 + h])
155+ h++;
156+ res[inv[i]] = h;
157+ if (h > 0 )
158+ h--;
159+ }
160+ return res;
161+ }
162162};
163163} // namespace kactl
164164
165165struct timeit {
166- decltype (chrono::high_resolution_clock::now()) begin;
167- const string label;
168- timeit (string label = " ???" ) : label(label) { begin = chrono::high_resolution_clock::now (); }
169- ~timeit () {
170- auto end = chrono::high_resolution_clock::now ();
171- auto duration = chrono::duration_cast<chrono::milliseconds>(end - begin).count ();
172- cerr << duration << " ms elapsed [" << label << " ]" << endl;
173- }
166+ decltype (chrono::high_resolution_clock::now()) begin;
167+ const string label;
168+ timeit (string label = " ???" ) : label(label) { begin = chrono::high_resolution_clock::now (); }
169+ ~timeit () {
170+ auto end = chrono::high_resolution_clock::now ();
171+ auto duration = chrono::duration_cast<chrono::milliseconds>(end - begin).count ();
172+ cerr << duration << " ms elapsed [" << label << " ]" << endl;
173+ }
174174};
175175
176176signed compare () {
177- srand (0 );
178- vi vS;
179- string S;
180- for (int iter = 0 ; iter < 5 ; iter++) {
177+ srand (0 );
178+ vi vS;
179+ string S;
180+ for (int iter = 0 ; iter < 5 ; iter++) {
181181
182- for (int i = 0 ; i < MAXN; i++) {
183- int t = rand () % 2 ;
184- vS.push_back (t + 1 );
185- S.push_back ((char )(t + ' a' ));
186- }
182+ for (int i = 0 ; i < MAXN; i++) {
183+ int t = rand () % 2 ;
184+ vS.push_back (t + 1 );
185+ S.push_back ((char )(t + ' a' ));
186+ }
187187
188- // cout << S << endl;
189- vector<array<int , 2 >> res;
190- {
191- timeit x (" kactl" );
192- old::SuffixArray kactl (S);
193- // cout << kactl.a[100] << endl;
194- auto lcp = kactl.lcp ();
188+ // cout << S << endl;
189+ vector<array<int , 2 >> res;
190+ {
191+ timeit x (" kactl" );
192+ old::SuffixArray kactl (S);
193+ // cout << kactl.a[100] << endl;
194+ auto lcp = kactl.lcp ();
195195 rep (i,0 ,sz (S)+1 )
196- res.push_back ({kactl.a [i], lcp[i]});
197- }
198- {
199- timeit x (" MIT" );
200- SuffixArray sa (S);
201- // cout << sa.sa[100] << endl;
196+ res.push_back ({kactl.a [i], lcp[i]});
197+ }
198+ {
199+ timeit x (" MIT" );
200+ SuffixArray sa (S);
201+ // cout << sa.sa[100] << endl;
202202 rep (i,0 ,sz (S)+1 ) {
203- assert ((res[i] == array<int , 2 >{sa.sa [i], sa.lcp [i]}));
204- }
205- }
206- }
203+ assert ((res[i] == array<int , 2 >{sa.sa [i], sa.lcp [i]}));
204+ }
205+ }
206+ }
207207 return 0 ;
208208}
209209
210210void fuzz (bool onlySmall = false ) {
211211 rep (large,0 ,2 ) {
212212 if (onlySmall && large) break ;
213- double work = large ? 1e8 : 5e5 ;
213+ double work = large ? 1e7 : 5e5 ;
214214 rep (alpha,1 ,27 ) {
215215 rep (n,0 ,100 ) {
216216 if (n * n * pow (alpha, n) > work) break ;
217- cout << alpha << ' ' << n << " : " << flush;
217+ // cout << alpha << ' ' << n << ": " << flush;
218218 string s (n, ' x' );
219- int cnt = 0 ;
220219 gen (s, 0 , alpha, [&]() {
221220 test (s, alpha);
222- cnt++;
223221 });
224- cout << cnt << endl;
225222 }
226223 }
227224 }
@@ -255,6 +252,7 @@ void perf2() {
255252int main () {
256253 // compare();
257254 fuzz (0 );
255+ cout<<" Tests passed!" <<endl;
258256 // perf();
259257 // perf2();
260258}
0 commit comments