제출 #1334584

#제출 시각아이디문제언어결과실행 시간메모리
1334584gohchingjaykArt Exhibition (JOI18_art)C++20
100 / 100
637 ms141340 KiB
#pragma GCC optimize("O3,inline")
#include <bits/stdc++.h>
 
using namespace std;
 
using ll = long long;
#define int ll

using ii = pair<int, int>;
using iii = pair<int, ii>;
using pvii = pair<vector<int>, ii>;
 
constexpr int MAXN = 500000 + 5;
constexpr int INF = 1e18 + 5;
constexpr int LOG = 20;

struct Node {
	Node *l, *r;
	int s, e, m;
	int max_dp = -INF; int min_e = INF; int max_e = -INF;
	int max_dp_addmin = 0; int max_dp_submax = 0;
	int max_v = -INF;
	bool lazymin = false; bool lazymax = false;
	int lazyminv = 0; int lazymaxv = 0;

	Node(int a, int b) {
		s = a; e = b; m = (s + e) / 2;
		if (s != e) {
			l = new Node(s, m);
			r = new Node(m+1, e);
		}
	}
	
	void apply_min(int x) {
		min_e = x;
		max_dp_addmin = max_dp + x;
		max_v = max_dp_submax + x;
		lazymin = true;
		lazyminv = x;
	}
	
	void apply_max(int x) {
		max_e = x;
		max_dp_submax = max_dp - x;
		max_v = max_dp_addmin - x;
		lazymax = true;
		lazymaxv = x;
	}

	void prop() {
		if (lazymin) {
			l->apply_min(lazyminv);
			r->apply_min(lazyminv);
		
			lazymin = false;
			lazyminv = 0;
		}
		
		if (lazymax) {
			l->apply_max(lazymaxv);
			r->apply_max(lazymaxv);
		
			lazymax = false;
			lazymaxv = 0;
		}
	}
	
	void retrieve() {
		max_dp = max(l->max_dp, r->max_dp);
		min_e = max(l->min_e, r->min_e);
		max_e = min(l->max_e, r->max_e);
		max_dp_addmin = max(l->max_dp_addmin, r->max_dp_addmin);
		max_dp_submax = max(l->max_dp_submax, r->max_dp_submax);
		max_v = max(l->max_v, r->max_v);
	}
	
	void range_set_min(int a, int b, int x) {
		if (b < s || e < a) return;
		if (a <= s && e <= b) {
			apply_min(x);
			return;
		}
		
		prop();
		l->range_set_min(a, b, x);
		r->range_set_min(a, b, x);
		
		retrieve();
	}
	
	void range_set_max(int a, int b, int x) {
		if (b < s || e < a) return;
		if (a <= s && e <= b) {
			apply_max(x);
			return;
		}
		
		prop();
		l->range_set_max(a, b, x);
		r->range_set_max(a, b, x);
	
		retrieve();
	}
	
	void point_set_dp(int p, int x) {
		if (s == e) {
			max_dp = x;
			max_dp_addmin = x + min_e;
			max_dp_submax = x - max_e;
			max_v = x - max_e + min_e;
			return;
		}
		
		prop();
		if (p <= m) l->point_set_dp(p, x);
		else r->point_set_dp(p, x);
		
		retrieve();
	}
	
	int range_max_v(int a, int b) {
		if (b < s || e < a) return -INF;
		if (a <= s && e <= b) return max_v;
		
		prop();
		
		return max(l->range_max_v(a, b), r->range_max_v(a, b));
	}
	
	int bsta_min(int x) {
		if (s == e) return s;
		
		prop();
		
		if (l->min_e > x) return l->bsta_min(x);
		if (r->min_e > x) return r->bsta_min(x);
		return INF;
	}
	
	int bsta_max(int x) {
		if (s == e) return s;
		
		prop();
		
		if (l->max_e < x) return l->bsta_max(x);
		if (r->max_e < x) return r->bsta_max(x);
		return INF;
	}
};

signed main() {
	ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

	int ans = -INF;
	int N; cin >> N;
	vector<ii> paintings(N);
	for (int i = 0; i < N; ++i) cin >> paintings[i].first >> paintings[i].second;
	sort(paintings.begin(), paintings.end());
	
	vector<int> pref(N+1);
	vector<int> sz(N+1);
	
	for (int i = 1; i <= N; ++i) {
		pref[i] = pref[i-1] + paintings[i-1].second;
		sz[i] = paintings[i-1].first;
	}
	
	Node *node = new Node(1, N);
	for (int i = 1; i <= N; ++i) {
		node->point_set_dp(i, -pref[i-1]);
		int m1 = node->bsta_max(sz[i]);
		if (m1 <= i) node->range_set_max(m1, i, sz[i]);
		int m2 = node->bsta_min(sz[i]);
		if (m2 <= i) node->range_set_min(m2, i, sz[i]);
		ans = max(ans, pref[i] + node->range_max_v(1, i));
	}
	
	cout << 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...