Guest User

Untitled

a guest
Sep 20th, 2024
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.11 KB | None | 0 0
  1. /***************************************************
  2. * Author  : Anav Prasad
  3. * Handle  : vrangr
  4. * Created : Fri Sep 20 20:31:58 IST 2024
  5. ****************************************************/
  6. #include <bits/stdc++.h>
  7.  
  8. #define debug(...) (void)42
  9. #ifdef LOCAL
  10.     #undef debug
  11.     #include <algo/debug.hpp>
  12.     const bool DEBUG = true;
  13. #else
  14.     [[maybe_unused]] const bool DEBUG = false;
  15. #endif
  16.  
  17. using namespace std;
  18.  
  19. typedef unsigned int uint;
  20. typedef long long int ll;
  21. typedef unsigned long long int ull;
  22. typedef long double ld;
  23. typedef __int128_t i128;
  24. #define endl "\n"
  25. #define fastIO ios_base::sync_with_stdio(false),cin.tie(0)
  26. #define TEST int T;cin>>T;while(T--)solve();
  27. #define TEST1 solve();
  28. #define all(x) (x).begin(), (x).end()
  29. #define rall(x) (x).rbegin(), (x).rend()
  30. #define sz(v) ((int)(v).size())
  31. #define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
  32. #define rep(...) GET_MACRO(__VA_ARGS__, forsn, debug, forn)(__VA_ARGS__)
  33. #define forn(i, n) for (__typeof(n) i = 0; i < n; i++)
  34. #define forsn(i, st, end, d) for(__typeof(end) i = st; (d>0?i<=end:i>=end); i+=((__typeof(end))d))
  35. template<typename type>inline void print_vec(const vector<type> &v){rep(i,sz(v))cout<<v[i]<<" \n"[i==sz(v)-1];}
  36. void solve();
  37.  
  38. int main() {
  39.     fastIO;
  40.     TEST;
  41. #ifdef LOCAL
  42.     cout << "\nTime elapsed: " << (double)clock() / CLOCKS_PER_SEC << " s.\n";
  43. #endif
  44.     return 0;
  45. }
  46.  
  47. // Based on https://codeforces.com/blog/entry/18051
  48. class segtree {
  49. public:
  50.     ll n, h;
  51.     vector<ll> tree, d;
  52.     segtree(ll gn) {
  53.         if (__builtin_popcountll(gn) != 1ll)
  54.             gn = (1ll << (64ll-__builtin_clzll(gn)));
  55.         n = gn;
  56.         gn<<=1ll;
  57.         tree.assign(gn,0ll);
  58.         d.assign(gn,LLONG_MIN);
  59.         h = 64ll-__builtin_clzll(gn);
  60.     }
  61.  
  62.     void calc(ll p, ll k) {
  63.         if (d[p] == 0) tree[p] = tree[p<<1ll] + tree[p<<1|1];
  64.         else tree[p] = d[p] * k;
  65.     }
  66.  
  67.     void apply(ll p, ll value, ll k) {
  68.         tree[p] = value * k;
  69.         if (p < n) d[p] = value;
  70.     }
  71.  
  72.     void build(ll l, ll r) {
  73.         ll k = 2;
  74.         for (l += n, r += n-1ll; l > 1ll; k <<= 1ll) {
  75.             l >>= 1ll, r >>= 1ll;
  76.             for (ll i = r; i >= l; --i) calc(i, k);
  77.         }
  78.     }
  79.  
  80.     void push(ll l, ll r) {
  81.         ll s = h, k = 1 << (h-1);
  82.         for (l += n, r += n-1; s > 0; --s, k >>= 1ll)
  83.             for (ll i = l >> s; i <= r >> s; ++i) if (d[i] != 0) {
  84.                 apply(i<<1, d[i], k);
  85.                 apply(i<<1|1, d[i], k);
  86.                 d[i] = 0;
  87.             }
  88.     }
  89.  
  90.     void modify(ll l, ll r, ll value) {
  91.         if (value == 0) return;
  92.         push(l, l + 1);
  93.         push(r - 1, r);
  94.         ll l0 = l, r0 = r, k = 1;
  95.         for (l += n, r += n; l < r; l >>= 1, r >>= 1, k <<= 1) {
  96.             if (l&1) apply(l++, value, k);
  97.             if (r&1) apply(--r, value, k);
  98.         }
  99.         build(l0, l0 + 1);
  100.         build(r0 - 1, r0);
  101.     }
  102.  
  103.     ll query(ll l, ll r) {
  104.         push(l, l + 1);
  105.         push(r - 1, r);
  106.         ll res = 0;
  107.         for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
  108.             if (l&1) res += tree[l++];
  109.             if (r&1) res += tree[--r];
  110.         }
  111.         return res;
  112.     }
  113. };
  114.  
  115. void solve() {
  116.     ll n; cin >> n;
  117.     vector<ll> a(n);
  118.     rep(i,n) cin >> a[i];
  119.     segtree seg(n);
  120.     rep(i,n) {
  121.         if (i == 0 || seg.query(i-1,i) <= a[i]) {
  122.             seg.modify(i,i+1,a[i]);
  123.             continue;
  124.         }
  125.         ll low = 0ll, high = i-1ll;
  126.         while(low < high) {
  127.             ll mid = (low+high)/2ll;
  128.             ll sum = seg.query(mid,i);
  129.             if ((sum+a[i])/(i-mid+1ll) <= seg.query(mid,mid+1ll))
  130.                 high = mid;
  131.             else low = mid+1ll;
  132.         }
  133.         assert(high < i);
  134.         ll sum = seg.query(high,i)+a[i], ct = i-high+1ll;
  135.         ll rem = sum%ct, avg = sum/ct;
  136.         seg.modify(high,high+ct-rem,avg);
  137.         if (rem) {
  138.             seg.modify(high+ct-rem,i+1ll,avg+1ll);
  139.             assert(i+1ll-(high+ct-rem) == rem);
  140.         }
  141.         if (high) assert(seg.query(high-1ll,high) <= seg.query(high,high+1ll));
  142.     }
  143.     cout << seg.query(n-1ll,n) - seg.query(0,1) << endl;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment