Tuesday, January 29, 2019

[Devskill] DCP-523: Everything equal 2

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : DCP-523: Everything equal 2
Source            : DevSkill
Category          : Data Structure
Algorithm         : Merge Sort Tree
Verdict           : Time Limit Exceeded

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll           long long int  
  6. #define inf          1e18  
  7.   
  8. static const int maxn = 5e4 + 5;  
  9.   
  10. struct MergeSortTree  
  11. {  
  12.       #define vll           vector <ll>  
  13.       #define eb            emplace_back  
  14.       #define sz(v)         (int)v.size()  
  15.   
  16.       vll v;  
  17.       vll stree;  
  18.   
  19.       inline void assignLeaf(ll val)  
  20.       {  
  21.             v.eb(val);  
  22.       }  
  23.       inline void marge(const MergeSortTree &lft, const MergeSortTree &rgt)  
  24.       {  
  25.             int lenLeft = sz(lft.v);  
  26.             int lenRight = sz(rgt.v);  
  27.             int idLeft = 0;  
  28.             int idRight = 0;  
  29.             while (idLeft < lenLeft && idRight < lenRight)  
  30.             {  
  31.                   ll numLeft = lft.v[idLeft];  
  32.                   ll numRight = rgt.v[idRight];  
  33.                   if (numLeft < numRight)  
  34.                   {  
  35.                         v.eb(numLeft);  
  36.                         ++idLeft;  
  37.                   }  
  38.                   else  
  39.                   {  
  40.                         v.eb(numRight);  
  41.                         ++idRight;  
  42.                   }  
  43.             }  
  44.             while (idLeft < lenLeft)  
  45.             {  
  46.                   v.eb(lft.v[idLeft]);  
  47.                   ++idLeft;  
  48.             }  
  49.             while (idRight < lenRight)  
  50.             {  
  51.                   v.eb(rgt.v[idRight]);  
  52.                   ++idRight;  
  53.             }  
  54.       }  
  55.       inline void reSize()  
  56.       {  
  57.             int len = sz(v);  
  58.             stree.resize(len+1);  
  59.       }  
  60.       inline void build()  
  61.       {  
  62.             int len = sz(v);  
  63.             stree[0] = v[0];  
  64.             for (int i = 1; i < len; i++) stree[i] = stree[i-1] + v[i];  
  65.       }  
  66.       inline ll getSum(int i, int j)  
  67.       {  
  68.             if (i > j) return 0;  
  69.             ll sum = stree[j];  
  70.             if (i > 0) sum -= stree[i-1];  
  71.             return sum;  
  72.       }  
  73.       inline int getPos(ll val) // return last index of value  
  74.       {  
  75.             int lo = 0;  
  76.             int hi = sz(v)-1;  
  77.             int ans = -1;  
  78.             while (lo <= hi)  
  79.             {  
  80.                   int mid = lo + (hi - lo) / 2;  
  81.                   //cerr << mid << " " << v[mid] << " " << val << endl;  
  82.                   if (v[mid] <= val)  
  83.                   {  
  84.                         ans = mid;  
  85.                         lo = mid + 1;  
  86.                   }  
  87.                   else  
  88.                   {  
  89.                         hi = mid - 1;  
  90.                   }  
  91.             }  
  92.             return ans;  
  93.       }  
  94.       inline ll sum(ll val)  
  95.       {  
  96.             int len = sz(v);  
  97.             if (len == 1)  
  98.             {  
  99.                   return abs(val - v[0]);  
  100.             }  
  101.             int pos = getPos(val);  
  102.             if (pos < 0) return inf;  
  103.             ll presum = getSum(0, pos);  
  104.             ll aftsum = getSum(pos+1, len-1);  
  105.             ll need = (aftsum - (len-1-pos) * val);  
  106.             need += ((pos+1) * val - presum);  
  107.             return need;  
  108.       }  
  109. } Tree[maxn << 2];  
  110.   
  111. ll arr[maxn];  
  112. int n, q;  
  113.   
  114. inline void build(int node, int a, int b)  
  115. {  
  116.       if (a == b)  
  117.       {  
  118.             Tree[node].assignLeaf(arr[a]);  
  119.             return;  
  120.       }  
  121.       int lft = node << 1;  
  122.       int rgt = lft | 1;  
  123.       int mid = (a + b) >> 1;  
  124.       build(lft, a, mid);  
  125.       build(rgt, mid+1, b);  
  126.       Tree[node].marge(Tree[lft], Tree[rgt]);  
  127.       Tree[node].reSize();  
  128.       Tree[node].build();  
  129. }  
  130.   
  131. inline ll query(int node, int a, int b, int i, int j, ll val)  
  132. {  
  133.       if (a == i && b == j)  
  134.       {  
  135.             //cerr << a << " " << b << " " << i << " " << j << endl;  
  136.             return Tree[node].sum(val);  
  137.       }  
  138.       int lft = node << 1;  
  139.       int rgt = lft | 1;  
  140.       int mid = (a + b) >> 1;  
  141.       ll res = 0;  
  142.       if (j <= mid)  
  143.       {  
  144.             res += query(lft, a, mid, i, j, val);  
  145.       }  
  146.       else if (i > mid)  
  147.       {  
  148.             res += query(rgt, mid+1, b, i, j, val);  
  149.       }  
  150.       else  
  151.       {  
  152.             res += query(lft, a, mid, i, mid, val);  
  153.             res += query(rgt, mid+1, b, mid+1, j, val);  
  154.       }  
  155.       return res;  
  156. }  
  157.   
  158. inline ll TernarySearch(int l, int r)  
  159. {  
  160.       ll lo = 1;  
  161.       ll hi = 1e9;  
  162.       ll mini = hi;  
  163.       ll ans = hi;  
  164.       while (1)  
  165.       {  
  166.             if (hi - lo <= 2)  
  167.             {  
  168.                   ll need = query(1, 1, n, l, r, lo);  
  169.                   if (need < mini) mini = need, ans = lo;  
  170.                   need = query(1, 1, n, l, r, lo+1);  
  171.                   if (need < mini) mini = need, ans = lo + 1;  
  172.                   need = query(1, 1, n, l, r, hi);  
  173.                   if (need < mini) mini = need, ans = hi;  
  174.                   break;  
  175.             }  
  176.             ll mid1 = lo + (hi - lo) / 3;  
  177.             ll mid2 = hi - (hi - lo) / 3;  
  178.             ll needMid1 = query(1, 1, n, l, r, mid1);  
  179.             ll needMid2 = query(1, 1, n, l, r, mid2);  
  180.             if (needMid1 < needMid2)  
  181.             {  
  182.                   if (needMid1 < mini) mini = needMid1, ans = mid1;  
  183.                   hi = mid2;  
  184.             }  
  185.             else  
  186.             {  
  187.                   if (needMid2 < mini) mini = needMid2, ans = mid2;  
  188.                   lo = mid1;  
  189.             }  
  190.       }  
  191.       //cerr << "ans " << ans << endl;  
  192.       return mini;  
  193. }  
  194.   
  195. int main()  
  196. {  
  197.       //freopen("in.txt", "r", stdin);  
  198.   
  199.       int tc;  
  200.       scanf("%d", &tc);  
  201.       for (int tcase = 1; tcase <= tc; tcase++)  
  202.       {  
  203.             scanf("%d %d", &n, &q);  
  204.             for (int i = 1; i <= n; i++) scanf("%d", arr+i);  
  205.             build(1, 1, n);  
  206.             while (q--)  
  207.             {  
  208.                   int l, r;  
  209.                   scanf("%d %d", &l, &r);  
  210.                   if (l == r)  
  211.                   {  
  212.                         puts("0");  
  213.                         continue;  
  214.                   }  
  215.                   ll need = TernarySearch(l, r);  
  216.                   printf("%lld\n", need);  
  217.             }  
  218.             for (int i = 0; i < (maxn << 2); i++)  
  219.             {  
  220.                   Tree[i].v.clear();  
  221.                   Tree[i].stree.clear();  
  222.             }  
  223.       }  
  224. }