Showing posts with label Merge Sort Tree. Show all posts
Showing posts with label Merge Sort Tree. Show all posts

Saturday, December 23, 2023

[Hackerearth] Curious Queries

 

Problem Link    : Curious Queries
Category        : Merge Sort Tree
Contest         : December Circuits'23  
#include "bits/stdc++.h"
using namespace std;
#define int     long long int
#define endl    '\n'
 
using pii = pair<int, int>;
 
const int maxn = 1e5 + 5;
 
struct MergesortTree {
    vector<pii> store;
    MergesortTree() {
        store.clear();
    }
 
    void assignLeaf(int val) {
        store.clear();
        store.push_back({val, val});
    }
    void marge(const MergesortTree &lchild, const MergesortTree &rchild) {
        int i = 0;
        int j = 0;
        store.clear();
        while (i < lchild.store.size() and j < rchild.store.size()) {
            if (lchild.store[i].first < rchild.store[j].first) {
                int sum = lchild.store[i].first + (store.size() ? store.back().second : 0);
                store.emplace_back(lchild.store[i].first, sum);
                i++;
            } else {
                int sum = rchild.store[j].first + (store.size() ? store.back().second : 0);
                store.emplace_back(rchild.store[j].first, sum);
                j++;
            }
        }
        while (i < lchild.store.size()) {
            int sum = lchild.store[i].first + (store.size() ? store.back().second : 0);
            store.emplace_back(lchild.store[i].first, sum);
            i++;
        }
        while (j < rchild.store.size()) {
            int sum = rchild.store[j].first + (store.size() ? store.back().second : 0);
            store.emplace_back(rchild.store[j].first, sum);
            j++;
        }
    }
    int getSum(int limit) {
        int id = upper_bound(store.begin(), store.end(), pii(limit, INT_MAX)) - store.begin();
        if (id == store.size()) {
            return 0;
        }
        int sum = store.back().second - (id - 1 >= 0 ? store[id - 1].second : 0);
        return sum;
    }
} Tree[maxn * 4];
 
int n;
int q;
int arr[maxn];
 
void build(int node, int a, int b) {
    if (a == b) {
        Tree[node].assignLeaf(arr[a]);
        return;
    }
    int lchild = node * 2;
    int rchild = node * 2 + 1;
    int mid = (a + b) / 2;
    build(lchild, a, mid);
    build(rchild, mid + 1, b);
    Tree[node].marge(Tree[lchild], Tree[rchild]);
}
 
int query(int node, int a, int b, int i, int j, int limit) {
    if (a > b or a > j or b < i) {
        return 0;
    }
    if (a >= i and b <= j) {
        return Tree[node].getSum(limit);
    }
    int lchild = node * 2;
    int rchild = node * 2 + 1;
    int mid = (a + b) / 2;
    int p = query(lchild, a, mid, i, j, limit);
    int q = query(rchild, mid + 1, b, i, j, limit);
    return p + q;
}
 
signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout.precision(12);
 
    bool FILEIO = 1;
    if (FILEIO and fopen("in.txt", "r")) {
        freopen("F2.txt", "r", stdin);
    }
 
    int tc;
    cin >> tc;
    for (int tcase = 1; tcase <= tc; tcase++) {
        cin >> n >> q;
        for (int i = 1; i <= n; i++) {
            cin >> arr[i];
        }
        build(1, 1, n);
        for (int i = 1; i <= q; i++) {
            int l, r;
            cin >> l >> r;
            l++;
            r++;
            int limit = arr[r];
            int ans = query(1, 1, n, 1, l, limit);
            cout << ans << " \n"[i == q];
        }
    }
}

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. }