제출 #557233

#제출 시각아이디문제언어결과실행 시간메모리
557233lunchboxCake 3 (JOI19_cake3)C++17
100 / 100
726 ms9548 KiB
/*
https://oj.uz/problem/view/JOI19_cake3
Cake 3
*/
#include <bits/stdc++.h>
using namespace std;

#define N	200000

namespace kactl {

	typedef long long ll;
#define sz(x)	int(x.size())

	/**
	 * Author: Lukas Polacek
	 * Date: 2009-10-30
	 * License: CC0
	 * Source: folklore/TopCoder
	 * Description: Computes partial sums a[0] + a[1] + ... + a[pos - 1], and updates single elements a[i],
	 * taking the difference between the old and new value.
	 * Time: Both operations are $O(\log N)$.
	 * Status: Stress-tested
	 */

	struct FT {
		vector<ll> s;
		vector<int> k;
		void init(int n) {
			s.assign(n, 0);
			k.assign(n, 0);
		}
		void update(int pos, ll dif, int c) { // a[pos] += dif
			// printf("upd[%d] {%lld, %d}\n", pos, dif, c);
			for (; pos < sz(s); pos |= pos + 1) {
				s[pos] += dif;
				k[pos] += c;
			}
		}
		ll query(int pos) { // sum of values in [0, pos)
			ll res = 0;
			for (; pos > 0; pos &= pos - 1) res += s[pos - 1];
			return res;
		}
		int lower_bound(int c) {// min pos st sum of [0, pos] >= sum
			// Returns n if no sum is >= sum, or -1 if empty sum is.
			if (c <= 0) return -1;
			int pos = 0; //ll sum = 0;
			for (int pw = 1 << 25; pw; pw >>= 1) {
				if (pos + pw <= sz(k) && k[pos + pw - 1] < c) {
					pos += pw, c -= k[pos - 1];
					// sum += s[pos-1];
				}
			}
			return pos;
		}
		ll q_(int c) {
			return query(lower_bound(c) + 1);
		}
	} ft;

}

array<int, 2> aa[N];
int ii[N];

int l_ = 0, r_ = -1, m_;

long long query(int l, int r) {
	if (r - l + 1 < m_)
		return -0x3f3f3f3f3f3f3f3f;
	// printf("QUERY [%d, %d]\n", l, r);
	while (l_ < l)
		kactl::ft.update(ii[l_], -aa[l_][1], -1), l_++;
	while (l_ > l)
		l_--, kactl::ft.update(ii[l_], +aa[l_][1], +1);
	while (r_ > r)
		kactl::ft.update(ii[r_], -aa[r_][1], -1), r_--;
	while (r_ < r)
		r_++, kactl::ft.update(ii[r_], +aa[r_][1], +1);
	// printf("%d | ", kactl::ft.lower_bound(m_));
	return kactl::ft.q_(m_) - (long long) 2 * (aa[r][0] - aa[l][0]);
}

long long ans = -0x3f3f3f3f3f3f3f3f;

void dnc(int lo, int ro, int l, int r) {
	long long tmp;
	int m, mo;

	if (l > r)
		return;
	m = (l + r) / 2, mo = lo;
	tmp = query(mo, m);
	// tmp = -0x3f3f3f3f3f3f3f3f;
	for (int i = lo; i <= ro; i++) {
		long long tmp_ = query(i, m);

		if (tmp_ > tmp) {
			tmp = tmp_;
			mo = i;
		}
	}
	ans = max(ans, tmp);
	if (mo == -1) {
		assert(0);
		dnc(lo, ro, m + 1, r);
	} else {
		dnc(lo, mo, l, m - 1);
		dnc(mo, ro, m + 1, r);
	}
}

int main() {
	static int ii_[N];
	int n;

	scanf("%d%d", &n, &m_);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &aa[i][1], &aa[i][0]);
		ii_[i] = i;
	}
	sort(aa, aa + n);
	sort(ii_, ii_ + n, [&](int i, int j) {
		return aa[i][1] > aa[j][1];
	});
	for (int i = 0; i < n; i++)
		ii[ii_[i]] = i;
	kactl::ft.init(n + 69);
	// for (int i = 0; i < n; i++)
	// 	printf("ii[%d]? = %d\n", i, ii[i]);
	// for (int i = 0; i < n; i++)
	// 	for (int j = i; j < n; j++)
	// 		ans = max(ans, query(i, j));
	// printf("q(%d, %d) = %lld\n", 0, 2, query(0, 2));
	dnc(0, n - 1, 0, n - 1);
	printf("%lld\n", ans);
	return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

cake3.cpp: In function 'int main()':
cake3.cpp:118:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  118 |  scanf("%d%d", &n, &m_);
      |  ~~~~~^~~~~~~~~~~~~~~~~
cake3.cpp:120:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  120 |   scanf("%d%d", &aa[i][1], &aa[i][0]);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...