Advertisement
999ms

Untitled

Sep 6th, 2020
1,530
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.96 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #define all(x) begin(x),end(x)
  3. #define make_unique(x) sort(all(x)); x.erase(unique(all(x)), end(x))
  4.  
  5. using namespace std;
  6. using ll = long long;
  7.  
  8. void InitIO(string filename = "") {
  9.     ios_base::sync_with_stdio(false);
  10.     cin.tie(nullptr);
  11.     cout.tie(nullptr);
  12.     if (filename.size()) {
  13.         freopen((filename + ".in").c_str(), "r", stdin);
  14.         freopen((filename + ".out").c_str(), "w", stdin);
  15.     }  
  16. }
  17.  
  18. struct SuffixArray {
  19.   const vector<int> s;
  20.   const int n;
  21.   vector<int> arr;
  22.   vector<int> lcp;
  23.   #define modulo(x) (x >= n ? x - n : x)
  24.   SuffixArray(const vector<int>& str)
  25.     : s(str)
  26.     , n(size(s))
  27.     , arr(n)
  28.     , lcp(n - 1)
  29.   {
  30.     vector<int> c(n), buff(n), ind(n), cnt(n);
  31.     iota(all(arr), 0);
  32.     stable_sort(all(arr), [&] (int i, int j) {
  33.         return s[i] < s[j];
  34.     });
  35.     c[arr[0]] = 0;
  36.     for (int i = 1; i < n; i++) {
  37.       c[arr[i]] = c[arr[i - 1]];
  38.       if (s[arr[i]] != s[arr[i - 1]]) {
  39.         c[arr[i]]++;
  40.       }
  41.     }
  42.     for (int deg = 1; (1 << (deg - 1)) < n; deg++) {
  43.       const int len = 1 << (deg - 1);
  44.       fill(all(cnt), 0);
  45.       ind[0] = 0;
  46.       for (int i = 0; i < n; i++) { arr[i] = modulo(arr[i] - len + n); }
  47.       for (int i = 0; i < n; i++) { cnt[c[arr[i]]]++; }
  48.       for (int i = 1; i < n; i++) { ind[i] = ind[i - 1] + cnt[i - 1]; }
  49.       for (int i = 0; i < n; i++) { buff[ind[c[arr[i]]]++] = arr[i]; }
  50.       copy(all(buff), begin(arr));
  51.       buff[arr[0]] = 0;
  52.       for (int i = 1; i < n; i++) {
  53.         buff[arr[i]] = buff[arr[i - 1]];
  54.         if (c[arr[i]] != c[arr[i - 1]] || c[modulo(arr[i] + len)] != c[modulo(arr[i - 1] + len)]) {
  55.           buff[arr[i]]++;
  56.         }
  57.       }
  58.       copy(all(buff), begin(c));
  59.     }
  60.     vector<int> pos(n);
  61.     for (int i = 0; i < n; i++) {
  62.       pos[arr[i]] = i;
  63.     }
  64.     int pre = 0;
  65.     for (int i = 0; i < n - 1; i++) {
  66.       int p = pos[i];
  67.       int len = min(n - 1 - i, n - 1 - arr[p - 1]);
  68.       int k = max(0, pre - 1);
  69.       lcp[p - 1] = k;
  70.       while (k < len && s[i + k] == s[arr[p - 1] + k]) { lcp[p - 1] = ++k; }
  71.       pre = k;
  72.     }
  73.   }
  74.   #undef modulo
  75. };
  76.  
  77. template<typename T>
  78. class TSparseTable {
  79. private:
  80.     int n, p;
  81.     vector<vector<T>> table;
  82.     vector<int> lg2;
  83. public:
  84.     void Operation(T& ans, T& left, T& right) {
  85.         ans = max(left, right);
  86.     }
  87.  
  88.     TSparseTable(const vector<T>& arr)
  89.         : n(arr.size())
  90.         , p(log2(n + 1) + 1)
  91.         , table(p, vector<T>(n, 0))
  92.     {
  93.         table[0] = arr;
  94.         for (int d = 1; d < p; d++) {
  95.             int dlt = 1 << (d - 1);
  96.             for (int i = 0; i + dlt < n; i++) {
  97.                 Operation(table[d][i], table[d - 1][i], table[d - 1][i + dlt]);
  98.             }
  99.         }
  100.         lg2.resize(n + 1);
  101.         lg2[0] = -1;
  102.         for (int i = 1; i <= n; i++) {
  103.             lg2[i] = lg2[i >> 1] + 1;
  104.         }
  105.     }
  106.  
  107.     T operator () (int l, int r) {
  108.         if (l > r) return 0;
  109.         int p = lg2[r - l + 1];
  110.         static T answer;
  111.         Operation(answer, table[p][l], table[p][r - (1 << p) + 1]);
  112.         return answer;
  113.     }
  114. };
  115.  
  116. unordered_map<int, ll> cache;
  117.  
  118. ll rec(int l, int r,  TSparseTable<int>& table, vector<int>& arr) {
  119.     if (l > r) return 0;
  120.     if (cache.count(l)) return cache[l];
  121.     int left = l;
  122.     int right = r;
  123.     int mid;
  124.     int cur = l;
  125.     while (left <= right) {
  126.         mid = (left + right) >> 1;
  127.         if (table(l, mid) == arr[l]) {
  128.             cur = mid;
  129.             left = mid + 1;
  130.         } else {
  131.             right = mid - 1;
  132.         }
  133.     }
  134.     ll res = (cur - l + 1) * 1ll * arr[l] + rec(cur + 1, r, table, arr);
  135.     return cache[l] = res;
  136. }
  137.  
  138.  
  139. void solve() {
  140.     int n;
  141.     cin >> n;
  142.     vector<int> arr(n);
  143.     cache = unordered_map<int, ll>();
  144.     for (int i = 0; i < n; i++) {
  145.         cin >> arr[i];
  146.     }
  147.     arr.push_back(0);
  148.     SuffixArray suffixArray(arr);
  149.     TSparseTable<int> table(arr);
  150.    
  151.     ll answer = 0;
  152.    
  153.     auto get = [&] (int from, int l, int r) {
  154.         //cout << from << ' ' << l << ' ' << r << '\n';
  155.         if (l > r) return 0ll;
  156.         ll value = table(from, l);
  157.         int left = l;
  158.         int right = r;
  159.         int mid;
  160.         int cur = l;
  161.         while (left <= right) {
  162.             mid = (left + right) >> 1;
  163.             if (table(from, mid) == value) {
  164.                 cur = mid;
  165.                 left = mid + 1;
  166.             } else {
  167.                 right = mid - 1;
  168.             }
  169.         }
  170.         return (cur - l + 1) * 1ll * value + rec(cur + 1, n - 1, table, arr);
  171.     };
  172.    
  173.     for (int i = 1; i <= n; i++) {
  174.         int index = suffixArray.arr[i];
  175.         //cout << "lcp " << suffixArray.lcp[index] << '\n';
  176.         answer += get(index, index + (index < n ? suffixArray.lcp[i - 1] : 0), n - 1);
  177.         //cout << answer << '\n';
  178.     }
  179.    
  180.     cout << answer << '\n';
  181. }
  182.  
  183. int main() {
  184.     InitIO();
  185.     int t;
  186.     cin >> t;
  187.     while (t--) {
  188.         solve();
  189.     }
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement