Submission #106182

#TimeUsernameProblemLanguageResultExecution timeMemory
106182mzhaoCake 3 (JOI19_cake3)C++11
0 / 100
3 ms384 KiB
#include <bits/stdc++.h>
using namespace std;

#ifdef DEBUG
#define D(x...) printf(x)
#else
#define D(x...)
#endif

#define MN 200100
#define x first
#define y second

using ll = long long;

ll N, M, pos[MN], ans = -1e17;
pair<ll, ll> A[MN], ord[MN];
pair<ll, ll> t[4*MN]; // (cnt, sum)

struct State {
	ll l, h; 		// where the endpoint can be [l, h)
	ll ansl, ansh; // where the optimal point can be [ansl, ansh)
};
vector<State> level[20];

void update(ll n, ll a, ll b, ll x, ll v) {
	if (a == b-1) {
		if (v > 0) t[n].x++;
		else t[n].x--;
		t[n].y += v;
	} else {
		int m = (a+b)/2;
		if (x < m) update(2*n, a, m, x, v);
		else update(2*n+1, m, b, x, v);
		t[n].x = t[2*n].x+t[2*n+1].x;
		t[n].y = t[2*n].y+t[2*n+1].y;
	}
}

ll query(ll n, ll a, ll b, ll x) {
	if (a == b-1) return t[n].y;
	int m = (a+b)/2;
	if (t[2*n].x >= x) return query(2*n, a, m, x);
	return t[2*n].y+query(2*n+1, m, b, x-t[2*n].x);
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> N >> M;
	for (int i = 0; i < N; i++) cin >> A[i].y >> A[i].x;
	sort(A, A+N); reverse(A, A+N);
	for (int i = 0; i < N; i++) ord[i] = {A[i].y, i};
	sort(ord, ord+N); reverse(ord, ord+N);
	for (int i = 0; i < N; i++) pos[ord[i].y] = i;
	level[0].push_back({0, N, 0, N});
	for (int i = 0; level[i].size(); i++) {
		D("LEVEL %d ===================\n", i);
		int curl = 0, curr = 0;
		for (State j : level[i]) {
			D("state = %lld %lld %lld %lld\n", j.l, j.h, j.ansl, j.ansh);
			int m = (j.l+j.h)/2;
			assert(curr <= m);
			while (curr <= m) {
				D("push in %d   %d %d\n", curr, pos[curr], A[curr].y);
				update(1, 0, N, pos[curr], A[curr].y);
				curr++;
			}
			assert(curl <= j.ansl);
			while (curl < j.ansl) {
				D("pop out %d   %d %d\n", curl, pos[curl], -A[curl].y);
				update(1, 0, N, pos[curl], -A[curl].y);
				curl++;
				assert(curl <= curr);
			}
			ll curbest = -1e17, curpos = -1;
			assert(curl < j.ansh);
			while (curr-curl >= M) {
				ll cur = query(1, 0, N, M)-2*A[curl].x;
				D("try %d   %d\n", curl, cur);
				if (cur > curbest) {
					curbest = cur;
					curpos = curl;
				}
				if (curl == j.ansh-1) break;
				update(1, 0, N, pos[curl], -A[curl].y);
				curl++;
			}
			D("curl = %d   curr = %d\n", curl, curr);
			if (curpos != -1) {
				if (j.l < j.h-1) {
					level[i+1].push_back({j.l, m, j.ansl, curpos+1});
					level[i+1].push_back({m, j.h, curpos, j.ansh});
				}
				ans = max(ans, curbest+2*A[m].x);
			}
			D("hello\n");
		}
		while (curl < curr) {
			update(1, 0, N, pos[curl], -A[curl].y);
			curl++;
		}
	}
	cout << ans << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...