답안 #1041165

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1041165 2024-08-01T16:30:17 Z Alihan_8 사탕 분배 (IOI21_candies) C++17
0 / 100
5000 ms 40516 KB
#include "candies.h"

#include <vector>

#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define ar array
#define pb push_back
#define ln '\n'
//#define int long long

using i64 = long long;

template <class F, class _S>
bool chmin(F &u, const _S &v){
    bool flag = false;
    if ( u > v ){
        u = v; flag |= true;
    }
    return flag;
}

template <class F, class _S>
bool chmax(F &u, const _S &v){
    bool flag = false;
    if ( u < v ){
        u = v; flag |= true;
    }
    return flag;
}

const i64 inf = 1e16;

const int N = 2e5 + 5;

//~ {
	//~ if ( l > tr or r < tl ){
		//~ return inf;
	//~ }
	
	//~ if ( l <= tl && tr >= r ){
		//~ if ( T[v].mx <= bound ){
			//~ return T[v].mn;
		//~ }
		
		//~ if ( l == r ) return inf;
			
		//~ int m = (l + r) / 2;
		
		//~ int ret = get(v * 2 + 1, m + 1, r, tl, tr);
		
		//~ if ( T[v * 2 + 1].mx <= bound ){
			//~ chmin(ret, get(v * 2, l, m, tl, tr));
		//~ } 
		
		//~ return ret;
	//~ }
//~ }

struct SegTree{
	vector <ar<i64,2>> T;
	
	vector <i64> lazy;
	
	int n;
	
	SegTree(int n) : n(n) {
		T.resize(N * 4);
		lazy.resize(N * 4);
		
		for ( int i = 0; i < N * 4; i++ ){
			T[i] = {inf, inf};
			
			lazy[i] = 0;
		}
	}
	
	void push(int v, int l, int r){
		if ( l != r ){
			lazy[v * 2] += lazy[v];
			lazy[v * 2 + 1] += lazy[v];
		}
		
		T[v][0] += lazy[v];
		T[v][1] -= lazy[v];
		lazy[v] = 0;
	}
	
	void upd(int v, int l, int r, int tl, int tr, i64 x){
		push(v, l, r);
		
		if ( l > tr or r < tl ) return;
		
		if ( tl <= l && tr >= r ){
			lazy[v] += x;
			
			push(v, l, r);
			
			return;
		}
		
		int m = (l + r) / 2;
		
		upd(v * 2, l, m, tl, tr, x);
		upd(v * 2 + 1, m + 1, r, tl, tr, x);
		
		for ( auto j: {0, 1} ){
			T[v][j] = min(T[v * 2][j], T[v * 2 + 1][j]);
		}
	}
	
	void upd(int l, int r, i64 x){
		upd(1, 0, n, l, r, x);
	}
	
	void set(int v, int l, int r, int ps, i64 x){
		push(v, l, r);
		
		if ( l == r ){
			T[v] = {x, -x};
			
			return;
		}
		
		int m = (l + r) / 2;
		
		if ( ps <= m ) set(v * 2, l, m, ps, x);
		else set(v * 2 + 1, m + 1, r, ps, x);
		
		for ( auto j: {0, 1} ){
			T[v][j] = min(T[v * 2][j], T[v * 2 + 1][j]);
		}
	}
	
	void set(int ps, i64 x){
		set(1, 0, n, ps, x);
	}
	
	i64 get(int v, int l, int r, int tl, int tr, int j){
		push(v, l, r);
		
		if ( l > tr or r < tl ) return inf;
		
		if ( tl <= l && tr >= r ){
			return T[v][j];
		}
		
		int m = (l + r) / 2;
		
		return min(get(v * 2, l, m, tl, tr, j), get(v * 2 + 1, m + 1, r, tl, tr, j));
	}
	
	i64 get(int l, int r, int j){ // 0 - min, 1 - max
		return get(1, 0, n, l, r, j) * (!j ? 1 : -1);
	}
	
	bool in(i64 l, i64 r, i64 u){ return l <= u && r >= u; } 
	
	i64 f(int v, int l, int r, int tl, int tr, i64 L, i64 R, int j){ 
		push(v, l, r);
		
		if ( l > tr or r < tl ) return inf;
		
		int m = (l + r) / 2;
		
		if ( tl <= l && tr >= r ){
			if ( !in(L, R, -T[v][1]) || !in(L, R, T[v][0]) ){
				return inf;
			}
			
			i64 ret = f(v * 2 + 1, m + 1, r, tl, tr, L, R, j);
			
			if ( in(L, R, -T[v * 2 + 1][1]) && in(L, R, T[v * 2 + 1][0]) ){
				chmin(ret, f(v * 2, l, m, tl, tr, L, R, j));
			}
			
			return ret;
		}
		
		//~ not finished
	}
};

struct Fenwick{
	vector <i64> fn;
	
	int n;
	
	Fenwick(int n) : fn(n + 1, 0), n(n) {}
	
	void upd(int i, int x){
		for (; i <= n; i += i & -i ){
			fn[i] += x;
		}
	}
	
	i64 get(int i){
		i64 ret = 0;
		
		for (; i > 0; i -= i & -i ){
			ret += fn[i];
		}
		
		return ret;
	}
	
	i64 get(int l, int r){
		return get(r) - get(l - 1);
	}
};

std::vector<int> distribute_candies(std::vector<int> c, std::vector<int> l,
                                    std::vector<int> r, std::vector<int> v) {
    
    int q = l.size(), n = c.size();
    
    vector <vector<int>> H(n + 1);
    
    for ( int i = 0; i < q; i++ ){
		H[l[i]].pb(i + 1);
		H[r[i] + 1].pb(-(i + 1));
	}
	
	vector <int> ans(n);
	
	SegTree seg(q);
	
	for ( int j = 0; j <= q; j++ ){
		seg.set(j, 0);
	}
	
	i64 pf = 0, mn = 0;
	
	for ( int j = 0; j < q; j++ ){
		pf += v[j];
		
		chmin(mn, pf);
	}
	
	Fenwick fn(q + 1);
	
	for ( int i = 0; i < n; i++ ){
		for ( auto &j: H[i] ){
			int u = abs(j);
			
			i64 x = j < 0 ? -v[u - 1] : v[u - 1];
			
			seg.upd(u, q, x);
			fn.upd(u, x);
		}
		
		auto ok = [&](int m){
			i64 mn = seg.get(m, q, 0), mx = seg.get(m, q, 1);
			
			//~ cout << "Min on Seg " << m << " " << q << " -> " << mn << ", " << mx << ln;
			
			if ( mx - mn >= c[i] ){
				return true;
			}
			
			{ // mx case
				int l = 0, r = m;
				
				while ( l < r ){
					int x = (l + r) / 2;
					
					if ( seg.get(x, m, 1) > mx ){
						l = x + 1;
					} else r = x;
				}
				
				if ( mx - seg.get(l, m, 0) >= c[i] ){
					return true;
				}
			}
			
			{ // mn case
				int l = 0, r = m;
				
				while ( l < r ){
					int x = (l + r) / 2;
					
					if ( seg.get(x, m, 0) < mn ){
						l = x + 1;
					} else r = x;
				}
				
				if ( seg.get(l, m, 1) - mn >= c[i] ){
					return true;
				}
			}
			
			return false;
		};
		
		//~ for ( int j = 1; j <= q; j++ ){
			//~ cout << (fn.get(j, j) != 0) <<  ' ';
		//~ } cout << ln;
		
		int l = 0, r = q + 1;
		
		while ( l + 1 < r ){
			int m = (l + r) / 2;
			
			if ( ok(m) ) l = m;
			else r = m;
		}
		
		//~ cout << i << " -> " << l << ln;
		
		if ( l == 0 ){ // no touch
			ans[i] = pf - mn;
		} else{
			ans[i] = fn.get(r, q);
			
			int t = -1;
			
			for ( int j = l; j > 0; j-- ){
				if ( fn.get(j, j) ){
					t = (fn.get(j, j) < 0 ? 0 : 1);
					
					break;
				}
			}
			
			assert(t != -1);
			
			ans[i] += c[i] * t;
		}
	}
	
	return ans;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 19036 KB Output is correct
2 Incorrect 4 ms 19008 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5033 ms 40516 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 5 ms 19036 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 19036 KB Output is correct
2 Correct 4 ms 19036 KB Output is correct
3 Correct 177 ms 28860 KB Output is correct
4 Correct 1410 ms 27116 KB Output is correct
5 Execution timed out 5062 ms 36364 KB Time limit exceeded
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 19036 KB Output is correct
2 Incorrect 4 ms 19008 KB Output isn't correct
3 Halted 0 ms 0 KB -