Submission #594261

#TimeUsernameProblemLanguageResultExecution timeMemory
594261senthetaDistributing Candies (IOI21_candies)C++17
29 / 100
2132 ms1065328 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...