sacgajcvs

Untitled

Oct 17th, 2020
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.47 KB | None | 0 0
  1. class Fun {
  2. vi p,c,lcp,logi;
  3. vector<vi> seg;
  4. string s1,s2,s;
  5. ll len1,len2;
  6.  
  7. Fun(string p, string q) {
  8. s1 = p;
  9. s2 = q;
  10. len1 = p.length();
  11. len2 = q.length();
  12. suffix_array(s1+'$'+s2);
  13. preprocess();
  14. }
  15.  
  16. ll findMatch(ll i,ll j) {
  17. return findLcp(i,len1 + 1 + j);
  18. }
  19.  
  20. // void showMe(string s) {
  21. // ll n = s.length();
  22. // rep(i,0,n) {
  23. // cerr << s.substr(p[i], n - p[i]) << " " << c[p[i]] << " " << lcp[i] << endl;
  24. // }
  25. // cerr << endl;
  26. // }
  27.  
  28. void count_sort() {
  29. ll n = p.size();
  30. vi count(n,0);
  31. trav(i,c) {
  32. count[i]++;
  33. }
  34. rep(i, 1, n) {
  35. count[i] += count[i - 1];
  36. }
  37. repr(i, 0, n - 1) {
  38. count[i + 1] = count[i];
  39. }
  40. count[0] = 0;
  41. vi p_new(n);
  42. trav(i,p) {
  43. p_new[count[c[i]]] = i;
  44. count[c[i]]++;
  45. }
  46. p = p_new;
  47. }
  48.  
  49.  
  50. void suffix_array(string s) {
  51. s += (char)0;
  52. ll n = s.length();
  53. p.resize(n);
  54. c.resize(n);
  55. lcp.resize(n);
  56.  
  57.  
  58. vi freq(256, 0);
  59. rep(i, 0, n) {
  60. freq[s[i]]++;
  61. }
  62. rep(i,1,256) {
  63. freq[i] += freq[i - 1];
  64. }
  65. repr(i,0,255) {
  66. freq[i + 1] = freq[i];
  67. }
  68. freq[0] = 0;
  69.  
  70.  
  71. p[0] = n - 1;
  72. rep(i, 0, n - 1) {
  73. p[freq[s[i]]] = i;
  74. freq[s[i]]++;
  75. }
  76.  
  77. c[p[0]] = 0;
  78. rep(i, 1, n) {
  79. if(s[p[i]] == s[p[i - 1]]) {
  80. c[p[i]] = c[p[i - 1]];
  81. } else {
  82. c[p[i]] = c[p[i - 1]] + 1;
  83. }
  84. }
  85.  
  86. // showMe(s);
  87.  
  88. vi c_new(n);
  89. ll k = 0;
  90. while((1 << k) < n) {
  91. rep(i, 0, n) {
  92. p[i] = (p[i] - (1 << k) + n) % n;
  93. }
  94. // DEBUG;
  95. count_sort();
  96. c_new[p[0]] = 0;
  97. pii pre,now;
  98. pre = {c[p[0]], c[(p[0] + (1 << k)) % n]};
  99. rep(i,1,n) {
  100. now = {c[p[i]], c[(p[i] + (1 << k)) % n]};
  101. if(now == pre) {
  102. c_new[p[i]] = c_new[p[i - 1]];
  103. } else {
  104. c_new[p[i]] = c_new[p[i - 1]] + 1;
  105. }
  106. pre = now;
  107. }
  108. k++;
  109. c = c_new;
  110. // showMe(s);
  111. }
  112.  
  113. k = 0;
  114. rep(i, 0, n - 1) {
  115. ll pi = c[i];
  116. ll j = p[pi - 1];
  117. while(s[i + k] == s[j + k]) {
  118. k++;
  119. }
  120. lcp[pi - 1] = k;
  121. k = max(k - 1, 0);
  122. }
  123. // showMe(s);
  124. }
  125.  
  126. ll findLcp(ll l,ll r) {
  127. l = c[l];
  128. r = c[r];
  129. if(l > r) {
  130. swap(l,r);
  131. }
  132. r--;
  133. ll lg = logi[r - l + 1];
  134. return min(seg[l][lg], seg[r - (1 << lg) + 1][lg]);
  135. }
  136.  
  137.  
  138. void preprocess() {
  139. ll n = sz(p) - 1;
  140.  
  141. logi.resize(n + 1);
  142.  
  143. logi[1] = 0;
  144.  
  145. rep(i, 2, n + 1) {
  146. logi[i] = logi[i / 2] + 1;
  147. }
  148.  
  149. ll lg = logi[n];
  150.  
  151. seg = vector<vi> (n, vi(lg + 1));
  152.  
  153. rep(i, 0, n) {
  154. seg[i][0] = lcp[i];
  155. }
  156.  
  157. for(ll j = 1; (1 << j) < n; j++) {
  158. rep(i, 0, n) {
  159. seg[i][j] = min(seg[i][j - 1], seg[min(n - 1, i + (1 << (j - 1)))][j - 1]);
  160. }
  161. }
  162. }
  163. }
Advertisement
Add Comment
Please, Sign In to add comment