Advertisement
Guest User

sqrtTREE

a guest
Jun 19th, 2019
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.68 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. //#pragma GCC optimize ("-O3,unroll-loops")
  3. #define FORN(n) for(int i = 0; i < n; i++)
  4. #define nl '\n'
  5. #define INF 1e9
  6. #define F first
  7. #define S second
  8. #define PB push_back
  9. #define INS insert
  10. #define ER erase
  11. using namespace std;
  12.  
  13. template<typename T> inline ostream & operator<< (ostream &_out, vector<T> &_v) { for (auto &_i : _v) { _out << _i << " "; } return _out; }
  14. template<typename T> inline istream & operator>> (istream &_in, vector<T> &_v) { for (auto &_i : _v) { _in >> _i; } return _in; }
  15.  
  16. mt19937 rnd(42);
  17.  
  18. typedef long long ll;
  19. typedef vector<long long> vl;
  20. typedef vector<vector<long long> > vvl;
  21. typedef pair<long long, long long> pl;
  22.  
  23. int mlog(int n) {
  24.     int k = 0;
  25.     while ((1 << k) < n)
  26.         k++;
  27.     return k;
  28. }
  29.  
  30. class sqrtTree {
  31.     int n, h;
  32.     vector<vvl> pref;
  33.     vector<vvl> suff;
  34.     vector<vvl> between;
  35.     vl squares;
  36.     public:
  37.         sqrtTree(vector<ll>& a);
  38.         bool valid(int l, int r, int blcksz);
  39.         pl findvalid(int l, int r);
  40.         ll request(int l, int r);
  41. };
  42.  
  43. sqrtTree::sqrtTree(vector<ll>& a) {
  44.     int csz, ccnt, csplit;
  45.     n = 1 << mlog(a.size());
  46.     h = (int)ceil(log2(log2((float)n)))+1;
  47.     a.resize(n, 0);
  48.     pref.resize(h), suff.resize(h), between.resize(h), squares.resize(h);
  49.     csz = n, csplit = n;
  50.     for (int i = 0; i < h; i++) {
  51.         squares[h-i-1] = csz;
  52.         ccnt = n / csz;
  53.         csplit /= csz;
  54.         pref[i].resize(ccnt, vector<ll>(csz)), suff[i].resize(ccnt, vector<ll>(csz)), between[i].resize(ccnt, vector<ll>(csplit));
  55.         for (int cblck = 0; cblck < ccnt; cblck++) {
  56.             pref[i][cblck][0] = a[cblck*csz], suff[i][cblck][csz-1] = a[cblck*csz+csz-1];
  57.             for (int j = 1; j < csz; j++)
  58.                 pref[i][cblck][j] = pref[i][cblck][j-1]+a[cblck*csz+j], suff[i][cblck][csz-1-j] = suff[i][cblck][csz-j] + a[cblck*csz+csz-1-j];
  59.         }
  60.         for (int cblck = 0; cblck < ccnt; cblck++) {
  61.             between[i][cblck][cblck%csplit] = pref[i][cblck][csz-1];
  62.             for (int j = cblck+1; j < ccnt && j%csplit < csplit && j%csplit != 0; j++)
  63.                 between[i][cblck][j%csplit] = between[i][cblck][j%csplit-1] + pref[i][j][csz-1];
  64.         }
  65.         csplit = csz;
  66.         csz = 1 << mlog(sqrt(csz));
  67.     }
  68.     return;
  69. }
  70.  
  71. bool sqrtTree::valid(int l, int r, int blcksz) {
  72.     if (blcksz > 2 && l/blcksz == r/blcksz && l%blcksz != 0 && r%blcksz != blcksz - 1) return false;
  73.     return true;
  74. }
  75.  
  76. pl sqrtTree::findvalid(int l, int r) {
  77.     int lh = 0, rh = h, mh;
  78.     while (rh - lh > 1) {
  79.         mh = (rh+lh)/2;
  80.         if (valid(l, r, squares[mh]))
  81.             lh = mh;
  82.         else
  83.             rh = mh;
  84.     }
  85.     if (l % squares[lh] == 0) return {l/squares[lh], lh};
  86.     else return {l/squares[lh]+1, lh};
  87. }
  88.  
  89. ll sqrtTree::request(int l, int r) {
  90.     if (l > r) swap(l, r);
  91.     pl val = findvalid(l, r);
  92.     ll ans = 0;
  93.     int lsqind = val.F*squares[val.S];
  94.     if (l < lsqind) ans += suff[h-val.S-1][val.F-1][squares[val.S]-lsqind+l];
  95.     int rsqind = lsqind + ((r-lsqind)/squares[val.S])*squares[val.S];
  96.     if (rsqind != lsqind) ans += between[h-val.S-1][val.F][rsqind/squares[val.S]-1];
  97.     if (r >= rsqind) ans += pref[h-val.S-1][rsqind/squares[val.S]][r-rsqind];
  98.     return ans;
  99. }
  100.  
  101. void read(vector<ll> &a) {
  102.     int n; cin >> n;
  103.     a.resize(n);
  104.     cin >> a;
  105.     return;
  106. }
  107.  
  108. void requests(sqrtTree& s) {
  109.     int m; cin >> m;
  110.     int u, v;
  111.     FORN(m) {
  112.         cin >> u >> v;
  113.         cout << s.request(u, v) << endl;
  114.     }
  115. }
  116.  
  117. int main() {
  118.     ios_base::sync_with_stdio(0);
  119.     cin.tie(0); cout.tie(0);
  120.     vector<ll> a;
  121.     read(a);
  122.     sqrtTree st(a);
  123.     requests(st);
  124.     return 0;
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement