peltorator

Disjoint Sparse Table: версия без дополнения до степени двойки

Feb 17th, 2021 (edited)
1,454
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.56 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. struct MaxCntAccumulator {
  6.     int segmentMax;
  7.     int maxCnt;
  8.  
  9.     MaxCntAccumulator() // Neutral element
  10.         : segmentMax(-1), maxCnt(0) {}
  11.  
  12.     MaxCntAccumulator(int arrayElem) // from a single value
  13.         : segmentMax(arrayElem), maxCnt(1) {}
  14.  
  15.     MaxCntAccumulator(int segmentMax, int maxCnt)
  16.         : segmentMax(segmentMax), maxCnt(maxCnt) {}
  17.  
  18.     MaxCntAccumulator operator+(const MaxCntAccumulator &other) { // accumulating function
  19.         if (segmentMax > other.segmentMax) {
  20.             return *this;
  21.         } else if (segmentMax < other.segmentMax) {
  22.             return other;
  23.         } else {
  24.             return MaxCntAccumulator(segmentMax, maxCnt + other.maxCnt);
  25.         }
  26.     }
  27. };
  28.  
  29. template<typename AccumType>
  30. struct DisjointSparseTable {
  31.     static const int MAXN = 1000001;
  32.     static const int LOG = 20;
  33.  
  34.     AccumType sparseTable[LOG][MAXN];
  35.  
  36.     template<typename InputType>
  37.     DisjointSparseTable(const vector<InputType> &arr) {
  38.         int n = arr.size();
  39.         int height = highestBit(n) + 1;
  40.         for (int lvl = 0; lvl < height; lvl++) {
  41.             int curLen = (1 << lvl);
  42.             for (int center = curLen; center < n + curLen; center += 2 * curLen) {
  43.                 AccumType prefAccum;
  44.                 for (int i = center; i < center + curLen && i <= n; i++) {
  45.                     sparseTable[lvl][i] = prefAccum;
  46.                     if (i != n) {
  47.                         prefAccum = prefAccum + AccumType(arr[i]);
  48.                     }
  49.                 }
  50.                 for (int i = min(n - 1, center - 1); i >= center - curLen; i--) {
  51.                     sparseTable[lvl][i] = AccumType(arr[i]) + sparseTable[lvl][i + 1];
  52.                 }
  53.             }
  54.         }
  55.     }
  56.  
  57.     int highestBit(int number) {
  58.         return 31 - __builtin_clz(number);
  59.     }
  60.  
  61.     AccumType query(int left, int right) { // [left, right)
  62.         int lvl = highestBit(left ^ right);
  63.         return sparseTable[lvl][left] + sparseTable[lvl][right];
  64.     }
  65. };
  66.  
  67. int main() {
  68.     int n;
  69.     cin >> n;
  70.     vector<int> arr(n);
  71.     for (int &elem : arr) {
  72.         cin >> elem;
  73.     }
  74.     DisjointSparseTable<MaxCntAccumulator> maxCntSparse(arr);
  75.  
  76.     int queriesNumber;
  77.     cin >> queriesNumber;
  78.     for (int i = 0; i < queriesNumber; i++) {
  79.         int left, right;
  80.         cin >> left >> right;
  81.         left--;
  82.         MaxCntAccumulator result = maxCntSparse.query(left, right);
  83.         cout << result.segmentMax << ' ' << result.maxCnt << '\n';
  84.     }
  85.     return 0;
  86. }
  87.  
Add Comment
Please, Sign In to add comment