Submission #530315

#TimeUsernameProblemLanguageResultExecution timeMemory
530315fhvirusCake 3 (JOI19_cake3)C++17
100 / 100
2249 ms17076 KiB
#include<bits/stdc++.h>
using namespace std;

struct Lisan: vector<int> {
	void done() { sort(begin(), end()); erase(unique(begin(), end()), end()); }
	const int operator () (const int& v) const { return lower_bound(begin(), end(), v) - begin(); }
};
struct DS {
	int N, M, lp, rp;
	vector<int> val;
	Lisan lisan;
	vector<int64_t> sum;
	vector<int> cnt;
	DS (int _M): M(_M), val(1, 0) {}
	void add(const int& v) { lisan.emplace_back(v); val.emplace_back(v); }
	void build() {
		lisan.done();
		N = lisan.size();
		lp = 1; rp = 0;
		sum.assign(N * 4, 0ll);
		cnt.assign(N * 4, 0);
	}
	void modify(int i, int l, int r, int p, int v) {
		if (l + 1 == r) {
			sum[i] += lisan[p] * v;
			cnt[i] += v;
			return;
		}
		int m = (l + r) / 2;
		if (p < m) modify(i * 2, l, m, p, v);
		else modify(i * 2 + 1, m, r, p, v);
		sum[i] = sum[i * 2] + sum[i * 2 + 1];
		cnt[i] = cnt[i * 2] + cnt[i * 2 + 1];
		return;
	}
	int64_t query(int i, int l, int r, int k) {
		if (l + 1 == r)
			return (int64_t) lisan[l] * k;
		if (cnt[i] == k)
			return sum[i];
		int m = (l + r) / 2;
		if (cnt[i * 2 + 1] >= k)
			return query(i * 2 + 1, m, r, k);
		return sum[i * 2 + 1] + query(i * 2, l, m, k - cnt[i * 2 + 1]);
	}
	void clean() {
		for (int i = lp; i <= rp; ++i)
			modify(1, 0, N, lisan(val[i]), -1);
		lp = 1; rp = 0;
	}
	int64_t query(int l, int r) {
		if (l < lp) clean();
		while (rp < r) modify(1, 0, N, lisan(val[++rp]),  1);
		while (lp < l) modify(1, 0, N, lisan(val[lp++]), -1);
		return query(1, 0, N, M);
	}
};

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	int N, M; cin >> N >> M;
	vector<pair<int, int>> cakes(N + 1);
	for (int i = 1; i <= N; ++i)
		cin >> cakes[i].second >> cakes[i].first;

	sort(begin(cakes) + 1, end(cakes));

	DS ds(M);
	for (int i = 1; i <= N; ++i)
		ds.add(cakes[i].second);
	ds.build();

	int64_t ans = LLONG_MIN;

	queue<tuple<int, int, int, int>> q;
	q.emplace(1, N - M + 1, M, N);
	while (!q.empty()) {
		auto [l, r, sl, sr] = q.front(); q.pop();
		r = min(r, sr - M + 1);
		if (l > r) continue;
		int m = (l + r) / 2;
		int bests = -1;
		int64_t bestv = LLONG_MIN;
		for (int i = max(sl, m + M - 1); i <= sr; ++i) {
			int64_t val = ds.query(m, i) - 2ll * (cakes[i].first - cakes[m].first);
			if (val > bestv) {
				bests = i;
				bestv = val;
			}
		}
		ans = max(ans, bestv);
		if (l <= m - 1) q.emplace(l, m - 1, sl, bests);
		if (m + 1 <= r) q.emplace(m + 1, r, bests, sr);
	}

	cout << ans << '\n';

	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...