Advertisement
K_Y_M_bl_C

Untitled

Nov 6th, 2017
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.65 KB | None | 0 0
  1. vi buildSuffArray(vi &s)
  2. {
  3. int n = s.size();
  4. vi p(n), cnt(256), c(n);
  5. for (int i = 0; i < n; ++i)
  6. ++cnt[s[i]];
  7. for (int i = 1; i < 256; ++i)
  8. cnt[i] += cnt[i - 1];
  9. for (int i = n - 1; i >= 0; --i)
  10. p[--cnt[s[i]]] = i;
  11. int ccnt = 1;
  12. c[p[0]] = 0;
  13. for (int i = 1; i < n; ++i)
  14. {
  15. if (s[p[i]] != s[p[i - 1]])
  16. ++ccnt;
  17. c[p[i]] = ccnt - 1;
  18. }
  19. for (int h = 0; (1 << h) < n; ++h)
  20. {
  21. vi pn(n), cn(n);
  22. cnt.assign(ccnt, 0);
  23. for (int i = 0; i < n; ++i)
  24. {
  25. pn[i] = p[i] - (1 << h);
  26. if (pn[i] < 0)
  27. pn[i] += n;
  28. }
  29. for (int i = 0; i < n; ++i)
  30. cnt[c[pn[i]]]++;
  31. for (int i = 1; i < ccnt; ++i)
  32. cnt[i] += cnt[i - 1];
  33. for (int i = n - 1; i >= 0; --i)
  34. p[--cnt[c[pn[i]]]] = pn[i];
  35. cn[p[0]] = 0;
  36. ccnt = 1;
  37. for (int i = 1; i < n; ++i)
  38. {
  39. int mid1 = (p[i] + (1 << h)) % n;
  40. int mid2 = (p[i - 1] + (1 << h)) % n;
  41. if (c[p[i]] != c[p[i - 1]] || c[mid1] != c[mid2])
  42. ++ccnt;
  43. cn[p[i]] = ccnt - 1;
  44. }
  45. if (ccnt == n)
  46. return p;
  47. swap(c, cn);
  48. }
  49. return p;
  50. }
  51.  
  52. vi buildLCP(vi &sa, vi &s)
  53. {
  54. int n = s.size();
  55. vi lcp(n);
  56. vi pos(n);
  57. int l = 0;
  58. for (int i = 0; i < n; ++i)
  59. {
  60. pos[sa[i]] = i;
  61. }
  62. for (int i = 0; i < n; ++i)
  63. {
  64. if (pos[i] == n - 1)
  65. {
  66. l = 0;
  67. continue;
  68. }
  69. l = max(l - 1, 0);
  70. int j = sa[pos[i] + 1];
  71. while (l < n && s[(i + l) % n] == s[(j + l) % n])
  72. ++l;
  73. lcp[pos[i]] = l;
  74. }
  75. return lcp;
  76. }
  77.  
  78. int solve(int n)
  79. {
  80. vi a(n);
  81. for (int i = 0; i < n; ++i)
  82. {
  83. scanf("%d", &a[i]);
  84. }
  85. vi sa = buildSuffArray(a);
  86. vi lcp = buildLCP(sa, a);
  87. ll ans = 0;
  88. for (int i = 0; i < n - 1; ++i)
  89. {
  90. ans += (ll)lcp[i];
  91. }
  92. printf("%lld\n", ans);
  93. return 0;
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement