Advertisement
Ritam_C

simple queries

May 17th, 2022
636
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.73 KB | None | 0 0
  1. const int N = 1e5+5;
  2. #define vll vector<int>
  3. #define ll long long
  4. const ll M = 1e9+7;
  5.  
  6. struct segTree {
  7.     int size = 1;
  8.     vll maxs;
  9.    
  10.     segTree(int n) {
  11.         while(size < n) size <<= 1;
  12.         maxs.assign((size << 1), 0);
  13.     }
  14.    
  15.     void _build(int n, vll& v, int x, int lx, int rx) {
  16.         if(rx-lx == 1) {
  17.             if(lx < n) maxs[x] = v[lx];
  18.             return;
  19.         }
  20.         int m = (lx+rx)/2;
  21.         _build(n, v, 2*x+1, lx, m);
  22.         _build(n, v, 2*x+2, m, rx);
  23.         maxs[x] = max(maxs[2*x+1], maxs[2*x+2]);
  24.     }
  25.    
  26.     void build(int n, vll& v) {
  27.         _build(n, v, 0, 0, size);
  28.     }
  29.    
  30.     void _set(int i, ll v, int x, int lx, int rx) {
  31.         if(rx-lx == 1) {
  32.             maxs[x] = v;
  33.             return;
  34.         }
  35.         int m = (lx+rx)/2;
  36.         if(i < m) _set(i, v, 2*x+1, lx, m);
  37.         else _set(i, v, 2*x+2, m, rx);
  38.         maxs[x] = max(maxs[2*x+1], maxs[2*x+2]);
  39.     }
  40.    
  41.     void set(int i, ll v) {
  42.         _set(i, v, 0, 0, size);
  43.     }
  44.    
  45.     ll _getMax(int l, int r, int x, int lx, int rx) {
  46.         if(l >= rx || lx >= r) return 0;
  47.         if(l <= lx && rx <= r) return maxs[x];
  48.         int m = (lx+rx)/2;
  49.         return max(_getMax(l, r, 2*x+1, lx, m), _getMax(l, r, 2*x+2, m, rx));
  50.     }
  51.    
  52.     ll getMax(int l, int r) {
  53.         return _getMax(l, r, 0, 0, size);
  54.     }
  55. };
  56.  
  57. int search(vector<pair<ll, ll>>& v, ll x) {
  58.     int l = 0, r = v.size()-1; ll ans = -1;
  59.     while(l <= r) {
  60.         int m = l+(r-l)/2;
  61.         if(v[m].second >= x) {
  62.             r = m-1;
  63.             ans = v[m].first;
  64.         } else {
  65.             l = m+1;
  66.         }
  67.     }
  68.     return ans;
  69. }
  70.  
  71. vector<int> Solution::solve(vector<int> &A, vector<int> &B) {
  72.     int n = A.size();
  73.     vector<long long> arr(N, 0);
  74.     vector<long long> prev(N, 0);
  75.     vector<long long> prod(N, 1);
  76.     segTree st(n); st.build(n, A);
  77.     for(int i = 0; i < n; i++) {
  78.         int l = i+1, r = n;
  79.         while(l <= r) {
  80.             int m = l+(r-l)/2;
  81.             if(st.getMax(i, m) == A[i]) l = m+1;
  82.             else r = m-1;
  83.         }
  84.         int l1 = prev[A[i]], r1 = i;
  85.         while(l1 <= r1) {
  86.             int m = l1+(r1-l1)/2;
  87.             if(st.getMax(m, i+1) == A[i]) r1 = m-1;
  88.             else l1 = m+1;
  89.         }
  90.         arr[A[i]] += (long long)(r-i)*(long long)(i-l1+1);
  91.         prev[A[i]] = (long long)(i+1);
  92.     }
  93.     for(int i = 1; i < N; i++) {
  94.         for(int j = i; j < N; j += i) {
  95.             prod[j] = (prod[j]*i)%M;
  96.         }
  97.     }
  98.     map<ll, ll> m;
  99.     for(int i = 1; i < N; i++) if(arr[i] > 0) m[prod[i]] += arr[i];
  100.     vector<pair<ll, ll>> v(m.begin(), m.end());
  101.     int p = v.size();
  102.     reverse(v.begin(), v.end());
  103.     for(int i = 1; i < p; i++) v[i].second += v[i-1].second;
  104.     //for(int i = 0; i < p; i++) cout << "(" << v[i].first << "," << v[i].second << ") ";
  105.     //cout << "\n";
  106.     vector<int> ans;
  107.     for(ll x : B) ans.push_back(search(v, x));
  108.     return ans;
  109. }
  110.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement