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
| #include <bits/stdc++.h> using namespace std;
typedef long long ll; #define MOD 1000000007 #define rep(i,a,n) for (ll i=a;i<n;i++) #define per(i,a,n) for (ll i=n;i-->(ll)a;) #define pb push_back
template<class T> void calc_sa_rank(vector<T>& arr, vector<int> &sa,vector<int> &rank, vector<int>&h){ int n = arr.size(); rank = vector<int>(n,0); sa = vector<int>(n,0); iota(sa.begin(),sa.end(), 0); sort(sa.begin(),sa.end(), [&](int i,int j){return arr[i] < arr[j];}); rep(i,1,n) rank[sa[i]] = rank[sa[i-1]] + !(arr[sa[i]] == arr[sa[i-1]]); for(int w = 1; w < n; w *= 2) { auto rank0 = rank; auto rk = [&](int i){return i < n ? rank0[i] : -1;}; sort(sa.begin(),sa.end(), [&](int i,int j){ return rk(i) != rk(j) ? rk(i) < rk(j) : rk(i+w) < rk(j+w); }); rank[sa[0]] = 0; rep(i,1,n) rank[sa[i]] = rank[sa[i-1]] + !(rk(sa[i]) == rk(sa[i-1]) && rk(sa[i]+w) == rk(sa[i-1]+w)); } h = vector<int>(n,0); int k = 0; rep(i,0,n) { if (rank[i] == 0) continue; if (k) --k; while (arr[i + k] == arr[sa[rank[i] - 1] + k]) ++k; h[rank[i]] = k; } }
int main() { char s[100] = "aabaaaab"; int n = strlen(s) ; printf("s:%s\n",s); vector<char> arr ; rep(i,0,n) arr.pb(s[i]); vector<int> sa; vector<int> rank; vector<int> h; calc_sa_rank(arr, sa, rank, h); printf("sa:\n"); rep(i,0,n) printf("%d %s\n", sa[i], s + sa[i]); printf("\nrk:\n"); rep(i,0,n) printf("%d %s\n", rank[i], s + i); printf("\nhei:"); rep(i,0,n) printf("%d ", h[i]); printf("\n"); return 0; }
|