Submission #594257

#TimeUsernameProblemLanguageResultExecution timeMemory
594257sentheta사탕 분배 (IOI21_candies)C++17
0 / 100
2801 ms2097152 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;

	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;
		//dbg(tl); dbg(tr);
		Node *nw = new Node;
		*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 = new Node;
		*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();

	// build fulltree
	fulltree = new Node;
	fulltree->build();
	rep(i,0,n){
		fulltree = fulltree->add(i,i, c[i]);
		//dbg(fulltree->qry(i));
	}

	Node *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...