This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "candies.h"
// author : sentheta aka vanwij
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<cassert>
#include<random>
#include<chrono>
#include<cmath>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
#define Int long long
#define V vector
#define pii pair<int,int>
#define ff first
#define ss second
#define rand() (uniform_int_distribution<int>(0,1<<30)(rng))
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define pow2(x) (1LL<<(x))
#define msb(x) (63-__builtin_clzll(x))
#define bitcnt(x) (__builtin_popcountll(x))
#define nl '\n'
#define _ << ' ' <<
#define all(x) (x).begin(), (x).end()
#define rep(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define dbg(x) if(1) cout << "?" << #x << " : " << (x) << endl << flush;
int n;
V<int> c;
#define mid ((tl+tr)/2)
struct Node{
int val=0, lz=0;
Node *lc=0, *rc=0;
bool ori;
void mark_ori(){
ori = 1;
if(lc){
lc->mark_ori(); rc->mark_ori();
}
}
void build(int tl=0,int tr=n-1){
if(tl==tr) return;
lc = new Node;
lc->build(tl, mid);
rc = new Node;
rc->build(mid+1,tr);
}
Node* add(int l,int r,int x,int tl=0,int tr=n-1){
if(r<tl || tr<l) return this;
Node *nw;
if(ori){
nw = new Node;
*nw = *this;
nw->ori = 0;
}
else{
nw = this;
}
if(l<=tl && tr<=r){
nw->val += x; nw->lz += x;
return nw;
}
if(lz){
lc = lc->add(tl,tr,lz, tl,mid);
rc = rc->add(tl,tr,lz, mid+1,tr);
lz = 0;
}
nw->lc = lc->add(l,r,x, tl,mid);
nw->rc = rc->add(l,r,x, mid+1,tr);
return nw;
}
Node* replace(int l,int r,Node *node,int tl=0,int tr=n-1){
if(r<tl || tr<l) return this;
Node *nw;
if(ori){
nw = new Node;
*nw = *this;
nw->ori = 0;
}
else{
nw = this;
}
if(l<=tl && tr<=r){
*nw = *node;
return nw;
}
if(lz){
lc = lc->add(tl,tr,lz, tl,mid);
rc = rc->add(tl,tr,lz, mid+1,tr);
lz = 0;
}
nw->lc = lc->replace(l,r, node->lc,tl,mid);
nw->rc = rc->replace(l,r, node->rc,mid+1,tr);
return nw;
}
int qry(int i,int tl=0,int tr=n-1){
if(tl==tr) return val;
if(lz){
lc = lc->add(tl,tr,lz, tl,mid);
rc = rc->add(tl,tr,lz, mid+1,tr);
lz = 0;
}
if(i<=mid) return lc->qry(i, tl,mid);
else return rc->qry(i, mid+1,tr);
}
};
Node *zerotree, *fulltree;
Node *root;
int q;
V<int> l, r, v;
V<int> distribute_candies(V<int>_c,V<int>_l,V<int>_r,V<int>_v) {
c = _c; l = _l; r = _r; v = _v;
n = c.size(); q = v.size();
// order idxs by c[i]
V<int> idxs(n);
rep(i,0,n) idxs[i] = i;
sort(all(idxs),[&](int i,int j){
return c[i] < c[j];
});
sort(all(c));
//for(int x : c) cout << x << " ";
//cout << nl;
// build zerotree
zerotree = new Node;
zerotree->build();
zerotree->mark_ori();
// build fulltree
fulltree = zerotree;
rep(i,0,n){
fulltree = fulltree->add(i,i, c[i]);
//dbg(fulltree->qry(i));
}
fulltree->mark_ori();
root = zerotree;
rep(i,0,q){
int x = abs(v[i]);
if(v[i] > 0){
// find max j s.t. c[j]-s[j]<=x
int j = -1;
// todo : segment tree walk
for(int J=1<<20; J; J/=2)
if(j+J<n && c[j+J]-root->qry(j+J)<=x) j+=J;
// 0..j -> set to full
if(0<=j) root = root->replace(0,j, fulltree);
// j+1..n-1 -> s[i]+=x
if(j+1<=n-1) root = root->add(j+1,n-1, x);
}
if(v[i] < 0){
// find max j s.t. c[i]<=x
int j = -1;
for(int J=1<<20; J; J/=2)
if(j+J<n && root->qry(j+J)<=x) j+=J;
// 0..j -> set to zero
if(0<=j) root = root->replace(0,j, zerotree);
// j+1..n-1 -> s[i]-=x
if(j+1<=n-1) root = root->add(j+1,n-1, -x);
}
}
V<int> ans(n);
rep(i,0,n){
ans[idxs[i]] = root->qry(i);
}
return ans;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |