Tuesday, March 19, 2019

[Codeforces] 840 - D. Destiny

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 840 - D. Destiny
Source            : Codeforces
Category          : Data Structure
Algorithm         : MO's Algorithm, Hilbert Order
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 310000;  
  6.   
  7. struct mo  
  8. {  
  9.       int l, r, k, id;  
  10.       int64_t ord;  
  11.       mo(int l = 0, int r = 0, int k = 0, int id = 0, int64_t ord = 0)  
  12.             : l(l)  
  13.             , r(r)  
  14.             , k(k)  
  15.             , id(id)  
  16.             , ord(ord)  
  17.             {}  
  18.   
  19.       friend bool operator < (mo p, mo q)  
  20.       {  
  21.             return p.ord < q.ord;  
  22.       }  
  23. } queries[maxn];  
  24.   
  25. inline int64_t hilbertOrder(int x, int y, int pow, int rotate)  
  26. {  
  27.       if (pow == 0)  
  28.       {  
  29.             return 0;  
  30.       }  
  31.     int hpow = 1 << (pow-1);  
  32.     int seg = (x < hpow) ? (  
  33.         (y < hpow) ? 0 : 3  
  34.     ) : (  
  35.         (y < hpow) ? 1 : 2  
  36.     );  
  37.     seg = (seg + rotate) & 3;  
  38.     const int rotateDelta[4] = {3, 0, 0, 1};  
  39.     int nx = x & (x ^ hpow), ny = y & (y ^ hpow);  
  40.     int nrot = (rotate + rotateDelta[seg]) & 3;  
  41.     int64_t subSquareSize = int64_t(1) << (2*pow - 2);  
  42.     int64_t ans = seg * subSquareSize;  
  43.     int64_t add = hilbertOrder(nx, ny, pow-1, nrot);  
  44.     ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);  
  45.     return ans;  
  46. }  
  47.   
  48. int arr[maxn], freq[maxn], ans[maxn];  
  49. int l = 1, r = 0;  
  50.   
  51. void add(int pos)  
  52. {  
  53.       int x = arr[pos];  
  54.       freq[x]++;  
  55. }  
  56.   
  57. void remov(int pos)  
  58. {  
  59.       int x = arr[pos];  
  60.       freq[x]--;  
  61. }  
  62.   
  63. int main()  
  64. {  
  65.       ios_base::sync_with_stdio(false);  
  66.       cin.tie(nullptr);  
  67.       #ifndef ONLINE_JUDGE  
  68.             freopen("in.txt""r", stdin);  
  69.       #endif // ONLINE_JUDGE  
  70.   
  71.       int n, q;  
  72.       cin >> n >> q;  
  73.       for (int i = 1; i <= n; i++) cin >> arr[i];  
  74.       for (int i = 1; i <= q; i++)  
  75.       {  
  76.             int l, r, k;  
  77.             cin >> l >> r >> k;  
  78.             int64_t ord = hilbertOrder(l, r, 21, 0);  
  79.             queries[i] = mo(l, r, k, i, ord);  
  80.       }  
  81.       sort(queries+1, queries+q+1);  
  82.       mt19937 rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());  
  83.       for (int i = 1; i <= q; i++)  
  84.       {  
  85.             int L = queries[i].l;  
  86.             int R = queries[i].r;  
  87.             int K = queries[i].k;  
  88.             while (l > L) add(--l);  
  89.             while (r < R) add(++r);  
  90.             while (l < L) remov(l++);  
  91.             while (r > R) remov(r--);  
  92.             int req = (R-L+1) / K;  
  93.             int op = 80;  
  94.             int mini = 1e9;  
  95.             while (op--)  
  96.             {  
  97.                   int idx = uniform_int_distribution <int> (L, R)(rng);  
  98.                   if (idx < L || idx > R) continue;  
  99.                   if (freq[ arr[idx] ] > req) mini = min(mini, arr[idx]);  
  100.             }  
  101.             if (mini == 1e9) mini = -1;  
  102.             ans[ queries[i].id ] = mini;  
  103.       }  
  104.       for (int i = 1; i <= q; i++) cout << ans[i] << '\n';  
  105. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.