-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSuffix_array(faster)
More file actions
51 lines (48 loc) · 1.44 KB
/
Copy pathSuffix_array(faster)
File metadata and controls
51 lines (48 loc) · 1.44 KB
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
// O(nlogn)
void count_sort(vector<int> &p,vector<int> &c){ // Sorts values in p by keys in c i.e, if c[p[i]] < c[p[j]] then i appears before j in p.
int n = p.size();
vector<int> cnt(n);
for(auto x : c) cnt[x]++;
vector<int> p_new(n),pos(n);
pos[0] = 0;
for(int i=1;i<n;++i) pos[i] = pos[i-1] + cnt[i-1];
for(auto x : p){
int i = c[x];
p_new[pos[i]] = x;
pos[i]++;
}
p = p_new;
}
vector<int> suffix_array(string s){
s += '$';
int n = s.size();
vector<int> p(n),c(n); // p stores suffix array and c stroes its equivalence class
{
// k = 0 phase
vector<pair<char,int>> a(n);
for(int i=0;i<n;++i) a[i] = {s[i],i};
sort(all(a));
for(int i=0;i<n;++i) p[i] = a[i].S;
c[p[0]] = 0;
for(int i=1;i<n;++i){
if(a[i].F == a[i-1].F) c[p[i]] = c[p[i-1]];
else c[p[i]] = c[p[i-1]] + 1;
}
}
int k=0;
while((1<<k) < n ){ // k -> k + 1
for(int i = 0; i < n ; ++i) p[i] = (p[i] - (1<<k) + n )%n;
count_sort(p,c);
vector<int> c_new(n);
c_new[p[0]] = 0;
for(int i=1;i<n;++i){
pii prev = {c[p[i-1]] , c[(p[i-1] + (1<<k))%n] } ;
pii now = {c[p[i]] , c[(p[i] + (1<<k))%n] } ;
if( now == prev) c_new[p[i]] = c_new[p[i-1]];
else c_new[p[i]] = c_new[p[i-1]] + 1;
}
c = c_new;
++k;
}
return p;
}