Guest User

Untitled

a guest
Jun 23rd, 2021
925
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.03 KB | None | 0 0
  1. #include "candies.h"
  2. #include <bits/stdc++.h>
  3.  
  4. using namespace std;
  5. using ll = long long;
  6. const int BS = 333;
  7.  
  8.  
  9. vector<ll> compute_function(const vector<int>& ops) {
  10.   vector<ll> stk;
  11.   stk.push_back(4e18);
  12.   stk.push_back(2e18);
  13.   for (auto delta : ops) {
  14.     if (delta == 0) continue;
  15.     if (delta > 0) {
  16.       ll rem = delta, px = 0;
  17.       while (true) {
  18.         ll x = stk.back();
  19.         if (x - px > rem) {
  20.           stk.push_back(px + rem);
  21.           stk.push_back(0);
  22.           break;
  23.         }
  24.         rem -= (x - px);
  25.         stk.pop_back();
  26.         px = stk.back();
  27.         stk.pop_back();
  28.       }
  29.     } else {
  30.       ll rem = -delta;
  31.       while (true) {
  32.         ll px = stk.back(); stk.pop_back();
  33.         ll x = stk.back();
  34.         if (x - px > rem) {
  35.           stk.push_back(px + rem);
  36.           break;
  37.         }
  38.         rem -= (x - px);
  39.         stk.pop_back();
  40.       }
  41.     }
  42.   }
  43.  
  44.   stk.push_back(0);
  45.   stk.push_back(0);
  46.   reverse(stk.begin(), stk.end());
  47.   return stk;
  48. }
  49.  
  50. vector<int> distribute_candies(
  51.     vector<int> c, vector<int> l,
  52.     vector<int> r, vector<int> v) {
  53.   int n = c.size();
  54.  
  55.  
  56.   // Sort each bucket increasingly by c[i] to facilitate easy evaluation of f.
  57.   vector<int> order(n);
  58.   iota(order.begin(), order.end(), 0);
  59.   for (int i = 0; i < n; i += BS) {
  60.     int j = min(i + BS, n);
  61.     sort(order.begin() + i, order.begin() + j, [&](int a, int b) {
  62.       return c[a] < c[b];
  63.     });
  64.   }
  65.  
  66.   vector<ll> stk;
  67.   vector<int> a(n, 0), na(n, 0);
  68.   vector<vector<int>> ops(n / BS + 1);
  69.  
  70.   auto commit = [&](int bi) {
  71.     if (ops[bi].empty()) return;
  72.     int l = bi * BS, r = min(n, (bi + 1) * BS);
  73.  
  74.     // compute f(.) and evaluate it in all c[i] of this bucket
  75.     auto stk = compute_function(ops[bi]);
  76.     ll value = 0;
  77.     int ptr = 0;
  78.     for (int i = l; i < r; ++i) {
  79.       int ci = c[order[i]];
  80.       while (stk[ptr + 1] < ci) {
  81.         if (ptr % 2 == 0)
  82.           value += stk[ptr + 1] - stk[ptr];
  83.         ++ptr;
  84.       }
  85.       if (ptr % 2 == 0) {
  86.         na[order[i]] = value + (ci - stk[ptr]);
  87.       } else {
  88.         na[order[i]] = value;
  89.       }
  90.     }
  91.  
  92.     // Adapt for non-zero initial values.
  93.     ll mind = 0, maxd = 0, nowd = 0;
  94.     for (auto x : ops[bi]) {
  95.       nowd += x;
  96.       mind = min(mind, nowd);
  97.       maxd = max(maxd, nowd);
  98.     }
  99.     for (int i = l; i < r; ++i) {
  100.       ll hi = min(c[i] - maxd, (ll)a[i]);
  101.       ll lo = -mind;
  102.       if (lo < hi)
  103.         na[i] += hi - lo;
  104.     }
  105.  
  106.     // Housekeeping.
  107.     for (int i = l; i < r; ++i)
  108.       a[i] = na[i];
  109.     ops[bi].clear();
  110.   };
  111.  
  112.   int q = l.size();
  113.   for (int i = 0; i < q; ++i) {
  114.     int bl = l[i] / BS, br = r[i] / BS;
  115.     commit(bl); commit(br);
  116.     for (int j = l[i]; j <= r[i]; ) {
  117.       if (j % BS == 0 && (j + BS - 1) <= r[i]) {
  118.         ops[j / BS].push_back(v[i]);
  119.         j += BS;
  120.       } else {
  121.         a[j] = max(0, min(a[j] + v[i], c[j]));
  122.         j += 1;
  123.       }
  124.     }
  125.   }
  126.  
  127.   for (int i = 0; i < n; i += BS)
  128.     commit(i / BS);
  129.   return a;
  130. }
Advertisement
Add Comment
Please, Sign In to add comment