Tuesday, December 3, 2019

[Spoj] SARRAY - Suffix Array

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : SARRAY - Suffix Array
Source            : Spoj
Category          : String, Data Structure
Algorithm         : Suffix Array
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 2e5 + 5;  
  6. static const int logn = 20;  
  7.   
  8. int p[maxn];  
  9. int pn[maxn];  
  10. int c[logn][maxn];  
  11. int cn[maxn];  
  12. int cnt[maxn];  
  13.   
  14. void sort_cyclic_shifts(string &s)  
  15. {  
  16.       int n = s.size();  
  17.       memset(cnt, 0, sizeof cnt);  
  18.       for (int i = 0; i < n; i++) cnt[ s[i] ]++;  
  19.       for (int i = 1; i < 256; i++) cnt[i] += cnt[i - 1];  
  20.       for (int i = 0; i < n; i++) p[ --cnt[ s[i] ] ] = i;  
  21.       int classes = 1;  
  22.       for (int i = 0; i < n; i++)  
  23.       {  
  24.             if (i && s[ p[i] ] != s[ p[i - 1] ]) classes++;  
  25.             c[0][ p[i] ] = classes - 1;  
  26.       }  
  27.       for (int k = 0; (1 << k) < n; k++)  
  28.       {  
  29.             for (int i = 0; i < n; i++)  
  30.             {  
  31.                   pn[i] = p[i] - (1 << k);  
  32.                   if (pn[i] < 0) pn[i] += n;  
  33.             }  
  34.             fill(cnt, cnt + classes, 0);  
  35.             for (int i = 0; i < n; i++) cnt[ c[k][ pn[i] ] ]++;  
  36.             for (int i = 1; i < classes; i++) cnt[i] += cnt[i - 1];  
  37.             for (int i = n - 1; i >= 0; i--) p[ --cnt[ c[k][ pn[i] ] ] ] = pn[i];  
  38.             classes = 1;  
  39.             cn[ p[0] ] = 0;  
  40.             pair <intint> x;  
  41.             pair <intint> y;  
  42.             for (int i = 1; i < n; i++)  
  43.             {  
  44.                   x = {c[k][ p[i] ], c[k][(p[i] + (1 << k)) % n]};  
  45.                   y = {c[k][ p[i - 1] ], c[k][(p[i - 1] + (1 << k)) % n]};  
  46.                   if (x != y) classes++;  
  47.                   cn[ p[i] ] = classes - 1;  
  48.             }  
  49.             for (int i = 0; i < n; i++) c[k + 1][i] = cn[i];  
  50.       }  
  51. }  
  52.   
  53. vector <int> suffix_array_construction(string s)  
  54. {  
  55.       s += "$";  
  56.       sort_cyclic_shifts(s);  
  57.       vector <int> sorted_shifts;  
  58.       int n = s.size();  
  59.       for (int i = 1; i < s.size(); i++) sorted_shifts.push_back(p[i]);  
  60.       return sorted_shifts;  
  61. }  
  62.   
  63. int compare(int i, int j, int substr_len, int n) // compare two equal length substring in O(1)  
  64. {  
  65.       // i = start index of first index  
  66.       // j = start index of second index  
  67.       // substr_len = length of sub-string  
  68.       // n = length of original string  
  69.       int k = __lg(substr_len);  
  70.       pair <intint> a = make_pair(c[k][i], c[k][(i + substr_len - (1 << k)) % n]);  
  71.       pair <intint> b = make_pair(c[k][j], c[k][(j + substr_len - (1 << k)) % n]);  
  72.       return a == b ? 0 : a < b ? -1 : 1;  
  73. }  
  74.   
  75. int longest_common_prefix(int i, int j)  
  76. {  
  77.       int ans = 0;  
  78.       for (int k = logn - 1; k >= 0; k--)  
  79.       {  
  80.             if (c[k][i] == c[k][j])  
  81.             {  
  82.                   ans += (1 << k);  
  83.                   i += (1 << k);  
  84.                   j += (1 << k);  
  85.             }  
  86.       }  
  87.       return ans;  
  88. }  
  89.   
  90. vector <int> lcp_construction(string const &s, vector <intconst &suffix_array)  
  91. {  
  92.       int n = s.size();  
  93.       vector <int> Rank(n, 0);  
  94.       for (int i = 0; i < n; i++) Rank[ suffix_array[i] ] = i;  
  95.       int k = 0;  
  96.       vector <int> lcp(n - 1, 0);  
  97.       for (int i = 0; i < n; i++)  
  98.       {  
  99.             if (Rank[i] == n - 1)  
  100.             {  
  101.                   k = 0;  
  102.                   continue;  
  103.             }  
  104.             int j = suffix_array[ Rank[i] + 1 ];  
  105.             while (i + k < n && j + k < n && s[i + k] == s[j + k]) k++;  
  106.             lcp[ Rank[i] ] = k;  
  107.             if (k) --k;  
  108.       }  
  109.       return lcp;  
  110. }  
  111.   
  112. signed main()  
  113. {  
  114.       ios_base::sync_with_stdio(false);  
  115.       cin.tie(nullptr);  
  116.       cout.tie(nullptr);  
  117.   
  118.       #ifndef ONLINE_JUDGE  
  119.             freopen("in.txt""r", stdin);  
  120.       #endif // ONLINE_JUDGE  
  121.   
  122.       string s;  
  123.       cin >> s;  
  124.       int n = s.size();  
  125.       vector <int> suffix_array = suffix_array_construction(s);  
  126.       vector <int> lcp = lcp_construction(s, suffix_array);  
  127.       for (int i = 0; i < n; i++)  
  128.       {  
  129.             int p = suffix_array[i];  
  130. //            cerr << i << " : " << p << ", " << s.substr(p, n - p + 1);  
  131. //            if (i < lcp.size()) cerr << ", " << lcp[i];  
  132. //            cerr << endl;  
  133.             cout << p << '\n';  
  134.       }  
  135.   
  136. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.