Advertisement
Malinovsky239

suff_array

Feb 1st, 2013
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.33 KB | None | 0 0
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <string>
  7. #include <vector>
  8. #include <map>
  9. #include <set>
  10. #include <cmath>
  11. #include <ctime>
  12. #include <cassert>
  13.  
  14. using namespace std;
  15.  
  16. #define pb push_back
  17. #define mp make_pair
  18. #define sz(A) (int)(A).size()
  19.  
  20. typedef unsigned long long LL;
  21. typedef long double LD;
  22.  
  23. const int N = 31715;
  24. const LL P = LL(1e9 + 7);
  25.  
  26. LL hash[N], p[N];
  27. char s[N];
  28. LL res;
  29. bool ok;
  30. int len;
  31.  
  32. pair<LL, int> sf[N];
  33.  
  34. LL count_hash(int l, int r) {
  35.     if (!l)
  36.         return hash[r];
  37.     else
  38.         return hash[r] - hash[l - 1] * p[r - l + 1];
  39. }
  40.  
  41. LL count_cycled(int l, int r) {
  42.     if (l < r)
  43.         return count_hash(l, r);
  44.     LL h = count_hash(l, len - 1) * p[r] + count_hash(0, l - 1);
  45.     return h;
  46. }
  47.  
  48. bool comp (pair<LL, int> a, pair<LL, int> b) {
  49.     int l = 0, r = len + 1;
  50.  
  51.     int p1 = a.second, p2 = b.second;
  52.  
  53.     while (l + 1 < r) {
  54.         int mid = (l + r) / 2;
  55.         if (count_cycled(p1, (p1 + mid - 1) % len) != count_cycled(p2, (p2 + mid - 1) % len))
  56.             r = mid;
  57.         else
  58.             l = mid;
  59.     }
  60. //  cerr << (s[p1]) << " " << s[p2] << endl;
  61.     cerr << l << endl;
  62.     return (s[(p1 + l) % len] < s[(p2 + l) % len]);
  63. }
  64.  
  65. int main()
  66. {
  67.     freopen("input.txt", "r", stdin);
  68.     freopen("output.txt", "w", stdout);
  69.  
  70.     gets(s);
  71.     len = strlen(s);
  72.  
  73.     s[len++] = char('z' + 1);
  74.  
  75.     p[0] = 1;
  76.     for (int i = 1; i <= len; i++)
  77.         p[i] = p[i - 1] * P;               
  78.  
  79.     hash[0] = s[0];
  80.     for (int i = 1; i < len; i++)
  81.         hash[i] = hash[i - 1] * P + s[i];
  82.  
  83.     for (int i = 0; i < len; i++) {
  84.         LL h = (i == 0 ? count_hash(0, len - 1) : count_cycled(i, i - 1));
  85.         sf[i] = mp(h, i);
  86.     }
  87.  
  88.     sort(sf, sf + len, comp);
  89.  
  90.     int Len = len - sf[0].second - 1;
  91.     res = Len * (Len + 1) / 2;
  92.  
  93. //  cerr << res << endl;
  94.  
  95.     for (int i = 1; i < len - 1; i++) {
  96.         int p1 = sf[i].second, p2 = sf[i - 1].second;      
  97.         int l = 0, r = len + 1;
  98.         while (l + 1 < r) {
  99.             int mid = (l + r) / 2;
  100.             if (count_cycled(p1, (p1 + mid - 1) % len) != count_cycled(p2, (p2 + mid - 1) % len))
  101.                 r = mid;
  102.             else
  103.                 l = mid;
  104.         }
  105.  
  106.         Len = len - sf[i].second - 1;
  107. //      res += (Len + 1) * Len / 2 - (l * (l + 1)) / 2;
  108.         res += (Len + l + 1) * (Len - l) / 2;
  109. //      cerr << res << endl;
  110.                        
  111.     }
  112.  
  113.     printf("%I64d\n", res);
  114.    
  115.     cerr << double(clock()) / CLOCKS_PER_SEC << endl;
  116.  
  117.     return 0;
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement