Monday, December 10, 2018

[toph.co] Rio and Inversion

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Rio and Inversion
Source            : toph.co
Category          : Data Structure
Algorithm         : Wavelet Tree
Verdict           : Accepted
  1. #include "bits/stdc++.h"  
  2.    
  3. using namespace std;  
  4.    
  5. #define FI              freopen("in.txt", "r", stdin)  
  6. #define FO              freopen("out.txt", "w", stdout)  
  7. #define FAST            ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)  
  8.    
  9. #define FOR(i, n)       for (int i = 1; i <= n; i++)  
  10. #define ROF(i, n)       for (int i = n; i >= 1; i--)  
  11. #define FORI(i, n)      for (auto i : n)  
  12. #define eb              emplace_back  
  13. #define ll              long long  
  14. #define All(a)          a.begin(), a.end()  
  15. #define lb              lower_bound  
  16. #define mod             1000000007  
  17.    
  18. static const int maxn = 1e5 + 5;  
  19. static const int logn = 18;  
  20.    
  21. struct waveletTree  
  22. {  
  23.       #define vi     vector <int>  
  24.       #define pb     push_back  
  25.    
  26.       int lo, hi;  
  27.       waveletTree *l, *r;  
  28.       vi b;  
  29.    
  30.       waveletTree(int *from , int *to, int x, int y)  
  31.       {  
  32.             lo = x, hi = y;  
  33.             if (from >= to || lo == hi) return;  
  34.             int mid = (lo + hi) >> 1;  
  35.             auto f = [mid](int x)  
  36.             {  
  37.                   return x <= mid;  
  38.             };  
  39.             b.reserve(to-from+1);  
  40.             b.pb(0); // for making 1 indexed  
  41.             for (auto it = from; it != to; it++) b.pb(b.back() + f(*it));  
  42.             auto pivot = stable_partition(from, to, f);  
  43.             l = new waveletTree(from, pivot, lo, mid);  
  44.             r = new waveletTree(pivot, to, mid+1, hi);  
  45.       }  
  46.       inline int LTE(int l, int r, int k)  
  47.       {  
  48.             if (l > r || k < lo) return 0;  
  49.             if (hi <= k) return (r - l + 1);  
  50.             int lb = b[l-1];  
  51.             int rb = b[r];  
  52.             return this->l->LTE(lb+1, rb, k) + this->r->LTE(l-lb, r-rb, k);  
  53.       }  
  54.       inline int EQL(int l, int r, int k)  
  55.       {  
  56.             if (l > r || k < lo || k > hi) return 0;  
  57.             if (lo == hi) return (r - l + 1);  
  58.             int lb = b[l-1];  
  59.             int rb = b[r];  
  60.             int mid = (lo + hi) >> 1;  
  61.             if (k <= mid) return this->l->EQL(lb+1, rb, k);  
  62.             return this->r->EQL(l-lb, r-rb, k);  
  63.       }  
  64.       ~waveletTree()  
  65.       {  
  66.             delete l;  
  67.             delete r;  
  68.       }  
  69. };  
  70.    
  71. int n, q;  
  72. int arr[maxn], temp[maxn];  
  73. ll inversion[maxn], tInversion, suminversion[maxn];  
  74.    
  75. int main()  
  76. {  
  77.       //FI;  
  78.       FAST;  
  79.    
  80.       cin >> n;  
  81.       FOR(i, n)  
  82.       {  
  83.             cin >> arr[i];  
  84.             arr[i]++;  
  85.             temp[i] = arr[i];  
  86.       }  
  87.       waveletTree *T;  
  88.       T = new waveletTree(temp+1, temp+n+1, 1, 100);  
  89.       FOR(i, n)  
  90.       {  
  91.             inversion[i] = T->LTE(i+1, n, arr[i]) - T->EQL(i+1, n, arr[i]);  
  92.             tInversion += inversion[i];  
  93.             suminversion[i] = tInversion;  
  94.       }  
  95.       int q;  
  96.       cin >> q;  
  97.       FOR(_q, q)  
  98.       {  
  99.             int type;  
  100.             cin >> type;  
  101.             if (type == 0) // swap  
  102.             {  
  103.                   int pos1, pos2;  
  104.                   cin >> pos1 >> pos2;  
  105.                   pos1++, pos2++;  
  106.                   if (pos1 > pos2) swap(pos1, pos2);  
  107.                   int val1 = arr[pos1];  
  108.                   int val2 = arr[pos2];  
  109.                   if (val1 == val2)  
  110.                   {  
  111.                         cout << tInversion << endl;  
  112.                         continue;  
  113.                   }  
  114.                   ll bad1 = T->LTE(pos1+1, pos2, val1) - T->EQL(pos1+1, pos2, val1);  
  115.                   ll add1 = (pos2 - pos1) - T->LTE(pos1+1, pos2, val1);  
  116.                   ll bad2 = (pos2-1 - pos1 + 1) - T->LTE(pos1, pos2-1, val2);  
  117.                   ll add2 = T->LTE(pos1, pos2-1, val2) - T->EQL(pos1, pos2-1, val2);  
  118.                   ll ans = tInversion - bad1 + add1 - bad2 + add2;  
  119.                   if (val1 > val2) ans++;  
  120.                   else ans--;  
  121.                   assert(ans >= 0);  
  122.                   cout << ans << endl;  
  123.             }  
  124.             else  
  125.             {  
  126.                   int l, r;  
  127.                   cin >> l >> r;  
  128.                   l++, r++;  
  129.                   if (l > r) swap(l, r);  
  130.                   int sub = suminversion[r] - suminversion[l-1];  
  131.                   FOR(i, 100)  
  132.                   {  
  133.                         int tequal = T->EQL(l, r, i);  
  134.                         if (tequal == 0) continue;  
  135.                         ll large = tequal * (l-1 - T->LTE(1, l-1, i));\  
  136.                         sub += large;  
  137.                   }  
  138.                   ll ans = tInversion - sub;  
  139.                   cout << ans << endl;  
  140.             }  
  141.       }  
  142. }  

No comments:

Post a Comment

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