답안 #806864

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
806864 2023-08-04T10:37:39 Z sentheta 사탕 분배 (IOI21_candies) C++17
27 / 100
875 ms 28956 KB
#include "candies.h"
#include<bits/stdc++.h>
using namespace std;

#define Int long long
#define V vector
#define pii pair<int,int>
#define ff first
#define ss second

static 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 0
#define cerr if(DBG) cout
#define dbg(x) {cerr << "?" << #x << " : " << (x) << endl << flush;}

const Int INF = 1e9+5;
const int N = 2e5+5;

int n, q;
V<int> c;
V<int> ql, qr, qv;


#define mid (tl+tr)/2
#define lc (v+1)
#define rc (v+2*(mid-tl+1))
// st.qry(t) = height at time t
struct St{
	Int mx[2*N], mn[2*N], lz[2*N];
	void upd(int l,int r,Int x,int v=0,int tl=0,int tr=q){
		if(r<tl || tr<l) return;
		if(l<=tl && tr<=r){
			mx[v] += x; mn[v] += x; lz[v] += x;
			return;
		}
		upd(l,r,x, lc,tl,mid);
		upd(l,r,x, rc,mid+1,tr);
		mx[v] = lz[v] + max(mx[lc], mx[rc]);
		mn[v] = lz[v] + min(mn[lc], mn[rc]);
	}
	Int qryMax(int l,int r=q,int v=0,int tl=0,int tr=q){
		if(r<tl || tr<l) return -INF*INF;
		if(l<=tl && tr<=r) return mx[v];
		return lz[v] + max({
			qryMax(l,r, lc,tl,mid), qryMax(l,r, rc,mid+1,tr)
		});
	}
	Int qryMin(int l,int r=q,int v=0,int tl=0,int tr=q){
		if(r<tl || tr<l) return INF*INF;
		if(l<=tl && tr<=r) return mn[v];
		return lz[v] + min({
			qryMin(l,r, lc,tl,mid), qryMin(l,r, rc,mid+1,tr)
		});
	}
} st;

// events
V<int> ev[N];

V<int> distribute_candies(V<int> _c,V<int> _ql,V<int> _qr,V<int> _qv){
	c.swap(_c); ql.swap(_ql); qr.swap(_qr); qv.swap(_qv);
	n = c.size();
	
	// dummy updates to guarantee both walls will be touched
	reverse(all(ql)); reverse(all(qr)); reverse(all(qv));
	ql.push_back(0); qr.push_back(n-1); qv.push_back(-INF);
	ql.push_back(0); qr.push_back(n-1); qv.push_back(+INF);
	reverse(all(ql)); reverse(all(qr)); reverse(all(qv));
	
	q = ql.size();
	
	// sort update events by l and r
	dbg(q);
	rep(i,0,q){
		cerr << ql[i] _ qr[i] _ qv[i] << nl;
		ev[ql[i]].push_back(i);
		ev[qr[i]+1].push_back(i);
	}
	cerr << nl;
	
	V<int> vans(n);
	rep(i,0,n){
		for(int e : ev[i]){
			// enable update
			if(ql[e]==i){
				st.upd(e,q, qv[e]);
			}
			// disable update
			else{
				st.upd(e,q, -qv[e]);
			}
			// rep(i,0,q) cerr << st.qryMax(i,i) << " ";
			// cerr << nl << nl;
		}
		
		// rep(i,0,q) cerr << st.qryMax(i,i) << " ";
		// cerr << nl << nl;
		
		// find last wall touch
		// if MAX-MIN>=c[i], that means in the future, we will touch another wall
		int t = 0;
		for(int J=1<<20; J; J/=2)
			if(t+J<q && st.qryMax(t+J)-st.qryMin(t+J)+1>=c[i]) t+=J;
		t++;
		
		dbg(t);
		dbg(st.qryMax(t));
		dbg(st.qryMin(t));
		dbg(st.qryMax(t)-st.qryMin(t));
		dbg(st.qryMax(t+1));
		dbg(st.qryMin(t+1));
		
		// find base wall and calculate ans
		Int ans;
		Int h = st.qryMax(q), base;
		// if last movement was UP, that means MAX is ceiling wall
		if(qv[t] > 0){
			base = st.qryMax(t) - c[i];
		}
		// if last movement was DOWN, that means MIN is floor/base wall
		else{
			base = st.qryMin(t);
		}
		// ans is relative height from base
		ans = h - base;
		vans[i] = ans;
		
		dbg(h);
		dbg(base);
		cerr << nl << nl;
		// if(i==1) return vans;
	}
	
	return vans;
	
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 3 ms 4948 KB Output is correct
3 Correct 4 ms 5204 KB Output is correct
4 Correct 4 ms 5204 KB Output is correct
5 Incorrect 6 ms 5204 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 798 ms 28144 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 198 ms 21388 KB Output is correct
3 Correct 267 ms 9464 KB Output is correct
4 Correct 875 ms 28928 KB Output is correct
5 Correct 867 ms 28956 KB Output is correct
6 Correct 660 ms 28540 KB Output is correct
7 Correct 640 ms 27420 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2 ms 4948 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 3 ms 4948 KB Output is correct
3 Correct 4 ms 5204 KB Output is correct
4 Correct 4 ms 5204 KB Output is correct
5 Incorrect 6 ms 5204 KB Output isn't correct
6 Halted 0 ms 0 KB -