cincout

suffix array O ( N log N ) + lcp

Mar 14th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.32 KB | None | 0 0
  1. void make(vector <int> &suf, vector <int> &cls, string s) {
  2. vector <pair<char, int>> ord;
  3. for (int i = 0; i < s.size(); ++i) {
  4. ord.push_back(make_pair(s[i], i));
  5. }
  6. int cur = -1;
  7. char prev = '0';
  8. sort(ord.begin(), ord.end());
  9. int j = 0;
  10. for (auto i : ord) {
  11. suf[j++] = i.second;
  12. if (i.first != prev) {
  13. cur++;
  14. }
  15. cls[i.second] = cur;
  16. prev = i.first;
  17. }
  18. }
  19.  
  20. vector <int> suffix_array(string s) {
  21. s = s + '#';
  22. int n = s.size();
  23. vector <int> suf(n), cls(n);
  24. make(suf, cls, s);
  25. int l = 0;
  26. while ((1 << l) < n) {
  27. vector <int> nowsort;
  28. for (int i = 0; i < n; ++i) {
  29. int cur = suf[i];
  30. int id = (cur - (1 << l) + n) % n;
  31. nowsort.push_back(id);
  32. }
  33. vector <int> beg(n), cnt(n);
  34. for (int i = 0; i < n; ++i) {
  35. cnt[cls[i]]++;
  36. }
  37. for (int i = 1; i < n; ++i) {
  38. beg[i] += beg[i - 1] + cnt[i - 1];
  39. }
  40. for (int i = 0; i < n; ++i) {
  41. int f = cls[nowsort[i]];
  42. suf[beg[f]++] = nowsort[i];
  43. }
  44. pair <int, int> prev = {-1, -1};
  45. int cur = -1;
  46. vector <int> newcls(n);
  47. for (int i = 0; i < n; ++i) {
  48. int ct = suf[i];
  49. pair <int, int> F = {cls[ct], cls[(ct + (1 << l)) % n]};
  50. if (F != prev) {
  51. cur++;
  52. }
  53. newcls[suf[i]] = cur;
  54. prev = F;
  55. }
  56. cls = newcls;
  57. l++;
  58. }
  59. vector <int> ans(n - 1);
  60. for (int i = 0; i < n - 1; ++i)
  61. ans[i] = suf[i + 1];
  62. return ans;
  63. }
  64.  
  65. vector <int> getLcp(vector <int> &suf, string s) {
  66. int n = suf.size();
  67. vector <int> pos(n);
  68. for (int i = 0; i < suf.size(); ++i)
  69. pos[suf[i]] = i;
  70. vector <int> lcp(n);
  71. for (int i = 0; i < n; i++) {
  72. if (pos[i] == n - 1) continue;
  73. int z = 0;
  74. if (i > 0 && pos[i - 1] != n - 1 && lcp[pos[i - 1]] > 0)
  75. z = lcp[pos[i - 1]] - 1;
  76. while (i + z < n && suf[pos[i] + 1] + z < n && s[i + z] == s[suf[pos[i] + 1] + z]) z++;
  77. lcp[pos[i]] = z;
  78. }
  79. int res = 0;
  80. for (int i = 1; i < n; i++) {
  81. res += n - suf[i] - lcp[i] - 1;
  82. }
  83. return lcp;
  84. }
Add Comment
Please, Sign In to add comment