답안 #435903

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
435903 2021-06-23T22:59:26 Z rqi 사탕 분배 (IOI21_candies) C++17
100 / 100
1193 ms 33944 KB
#include "candies.h"
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

typedef vector<int> vi;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<pi> vpi;

#define mp make_pair
#define f first
#define s second
#define pb push_back
#define ins insert
#define bk back()
#define lb lower_bound

#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()

void ckmin(int& a, int b){
	a = min(a, b);
}

void ckmax(int& a, int b){
	a = max(a, b);
}

void ckmin(ll& a, ll b){
	a = min(a, b);
}

void ckmax(ll& a, ll b){
	a = max(a, b);
}

const ll INF = 1e18;
const int MOD = 1e9+7;

const int mx = 200005;
const int SZ = 262144;

pl mnmx[2*SZ];
ll lazy[2*SZ];

void pull(int ind){
	mnmx[ind] = mp(min(mnmx[2*ind].f, mnmx[2*ind+1].f), max(mnmx[2*ind].s, mnmx[2*ind+1].s));
}

void build(){
	for(int i = SZ-1; i >= 1; i--){
		pull(i);
	}
}

void push(int ind){
	mnmx[ind].f+=lazy[ind];
	mnmx[ind].s+=lazy[ind];
		
	if(2*ind+1 < 2*SZ){
		for(int i = 0; i < 2; i++){
			assert(2*ind+i < 2*SZ);
			lazy[2*ind+i]+=lazy[ind];
		}
	}
	

	lazy[ind] = 0;
}



void update(int l, int r, ll val, int ind = 1, int L = 0, int R = SZ-1){
	push(ind);
	if(l > R || r < L) return;
	if(l <= L && R <= r){
		lazy[ind]+=val;
		push(ind);
		return;
	}

	int M = (L+R)/2;

	update(l, r, val, 2*ind, L, M);
	update(l, r, val, 2*ind+1, M+1, R);

	pull(ind);
}

ll tot_sum = 0;

int query(ll D, pl q_MNMX = mp(INF, -INF), int ind = 1, int L = 0, int R = SZ-1){ //return -1 if inconclusive
	push(ind);

	// if(D == 17 && R <= 9){
	// 	cout << "L, R: " << L << " " << R << " " << q_MNMX.f << " " << q_MNMX.s << "\n";
	// 	cout << mnmx[ind].f << " " << mnmx[ind].s << "\n";
	// }

	pl entire = mp(min(q_MNMX.f, mnmx[ind].f), max(q_MNMX.s, mnmx[ind].s));

	if(q_MNMX.s-q_MNMX.f >= D) return MOD;

	// if(L == 2 && R == 3){
	// 	cout << "entire: " << entire.f << " " << entire.s << "\n";
	// }
	if(entire.s-entire.f < D) return L;

	// if(L == 2 && R == 3){
	// 	cout << "entire: " << entire.f << " " << entire.s << "\n";
	// }
	if(L == R){
		return MOD;
	}

	int M = (L+R)/2;

	
	// cout << L << " " << R << " " << "querying second half" << "\n";
	int res = query(D, q_MNMX, 2*ind+1, M+1, R);
	if(res > M+1){
		return res;
	}

	assert(res == M+1);

	pl half = mp(min(q_MNMX.f, mnmx[2*ind+1].f), max(q_MNMX.s, mnmx[2*ind+1].s));
	int res2 = query(D, half, 2*ind, L, M);

	res = min(res, res2);

	// if(D == 17 && R <= 9){
	// 	cout << "L, R:" << L << " " << R << "\n";
	// 	cout << "res: " << res << "\n";
	// }
	return res;
}

pl queryMnMx(int l, int r, int ind = 1, int L = 0, int R = SZ-1){
	push(ind);

	if(r < L || R < l) return mp(INF, -INF);

	if(l <= L && R <= r){
		return mnmx[ind];
	}

	int M = (L+R)/2;
	pl res1 = queryMnMx(l, r, 2*ind, L, M);
	pl res2 = queryMnMx(l, r, 2*ind+1, M+1, R);

	return mp(min(res1.f, res2.f), max(res1.s, res2.s));
}

int n, q;

// int query(ll D){
// 	int lo = 0;
// 	int hi = q;
// 	while(lo < hi){
// 		int mid = (lo+hi)/2;

// 		bool works = 0;

// 		pl a = queryMnMx(mid, q);
// 		if(a.s-a.f < D){
// 			works = 1;
// 		}

// 		if(works){
// 			hi = mid;
// 		}
// 		else{
// 			lo = mid+1;
// 		}
// 	}
// 	return lo;
// }

vector<pair<int, ll>> updates[mx];

vi distribute_candies(vi c, vi l, vi r, vi v) {
    n = sz(c);
    q = sz(l);
    vi s(n, 0);

    for(int i = 0; i < q; i++){
    	updates[l[i]].pb(mp(i, v[i]));
    	updates[r[i]+1].pb(mp(i, -v[i]));
    }

    for(int i = q+1; i < SZ; i++){
    	mnmx[SZ+i] = mp(INF, -INF);
    }
    build();

    for(int i = 0; i < n; i++){
    	// cout << "i = " << i << "\n";
    	for(auto u: updates[i]){
    		update(u.f+1, q, u.s);
    	}

    	ll D = c[i];
    	ll tot = queryMnMx(q, q).f;

    	int pos = query(D);

    	// cout << D << " " << tot << " " << pos << "\n";
    	// cout.flush();


   		if(pos == 0){
   			pl a = queryMnMx(0, q);
   			s[i] = (int)(tot-a.f);
   		}
   		else{
   			// cout << "seg: ";
   			// for(int i = 0; i <= q; i++){
   			// 	pl a = queryMnMx(i, i);
   			// 	cout << a.f << " ";
   			// }
   			// cout << "\n";
   			// cout.flush();
   			pl a = queryMnMx(pos-1, q);
   			ll ext_val = queryMnMx(pos-1, pos-1).f;


   			// cout << a.f << " " << a.s << " " << ext_val << "\n";
   			// cout.flush();
   			if(ext_val == a.f){
   				s[i] = (int)(D-(a.s-tot));
   			}
   			else{
   				assert(ext_val == a.s);
   				s[i] = (int)(tot-a.f);
   			}
   		}
    }

    return s;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 13132 KB Output is correct
2 Correct 9 ms 13132 KB Output is correct
3 Correct 12 ms 13436 KB Output is correct
4 Correct 13 ms 13388 KB Output is correct
5 Correct 17 ms 13452 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1138 ms 33860 KB Output is correct
2 Correct 1151 ms 33872 KB Output is correct
3 Correct 1092 ms 33864 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 13260 KB Output is correct
2 Correct 583 ms 29952 KB Output is correct
3 Correct 430 ms 16940 KB Output is correct
4 Correct 1121 ms 33944 KB Output is correct
5 Correct 1160 ms 33924 KB Output is correct
6 Correct 1133 ms 33876 KB Output is correct
7 Correct 1097 ms 33884 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 13132 KB Output is correct
2 Correct 11 ms 13260 KB Output is correct
3 Correct 252 ms 27408 KB Output is correct
4 Correct 367 ms 15844 KB Output is correct
5 Correct 602 ms 30008 KB Output is correct
6 Correct 640 ms 29972 KB Output is correct
7 Correct 635 ms 29912 KB Output is correct
8 Correct 581 ms 29932 KB Output is correct
9 Correct 693 ms 29904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 13132 KB Output is correct
2 Correct 9 ms 13132 KB Output is correct
3 Correct 12 ms 13436 KB Output is correct
4 Correct 13 ms 13388 KB Output is correct
5 Correct 17 ms 13452 KB Output is correct
6 Correct 1138 ms 33860 KB Output is correct
7 Correct 1151 ms 33872 KB Output is correct
8 Correct 1092 ms 33864 KB Output is correct
9 Correct 10 ms 13260 KB Output is correct
10 Correct 583 ms 29952 KB Output is correct
11 Correct 430 ms 16940 KB Output is correct
12 Correct 1121 ms 33944 KB Output is correct
13 Correct 1160 ms 33924 KB Output is correct
14 Correct 1133 ms 33876 KB Output is correct
15 Correct 1097 ms 33884 KB Output is correct
16 Correct 8 ms 13132 KB Output is correct
17 Correct 11 ms 13260 KB Output is correct
18 Correct 252 ms 27408 KB Output is correct
19 Correct 367 ms 15844 KB Output is correct
20 Correct 602 ms 30008 KB Output is correct
21 Correct 640 ms 29972 KB Output is correct
22 Correct 635 ms 29912 KB Output is correct
23 Correct 581 ms 29932 KB Output is correct
24 Correct 693 ms 29904 KB Output is correct
25 Correct 9 ms 13132 KB Output is correct
26 Correct 322 ms 15800 KB Output is correct
27 Correct 610 ms 30020 KB Output is correct
28 Correct 1020 ms 33892 KB Output is correct
29 Correct 1138 ms 33860 KB Output is correct
30 Correct 1159 ms 33860 KB Output is correct
31 Correct 1193 ms 33864 KB Output is correct
32 Correct 1144 ms 33864 KB Output is correct