제출 #102477

#제출 시각아이디문제언어결과실행 시간메모리
102477AngusRitossaCake 3 (JOI19_cake3)C++14
100 / 100
2252 ms197944 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m;
ll ans = -1e15;
pair<ll, ll> a[200010];
struct Node
{
	ll val, am, left, right;
};
Node rangetree[10000000];
int upto;
int roots[200010];
void update(ll node, int curr, int oldcurr, int cstart = 0, int cend = 1e9+1)
{
	if (cstart == cend)
	{
		rangetree[curr].val = rangetree[oldcurr].val + node;
		rangetree[curr].am = rangetree[oldcurr].am + 1;
		return;
	}
	int mid = (cstart+cend)/2;
	if (node <= mid)
	{
		rangetree[curr].right = rangetree[oldcurr].right;
		rangetree[curr].left = ++upto;
		update(node, rangetree[curr].left, rangetree[oldcurr].left, cstart, mid);
	}
	else
	{
		rangetree[curr].left = rangetree[oldcurr].left;
		rangetree[curr].right = ++upto;
		update(node, rangetree[curr].right, rangetree[oldcurr].right, mid+1, cend);
	}
	rangetree[curr].val = rangetree[rangetree[curr].left].val + rangetree[rangetree[curr].right].val;
	rangetree[curr].am = rangetree[rangetree[curr].left].am + rangetree[rangetree[curr].right].am;
}
ll treewalk(ll am, int curr, int oldcurr, int cstart = 0, int cend = 1e9+1)
{
	if (cstart == cend)
	{
		return am * (ll)cstart;
	}
	int mid = (cstart+cend)/2;
	if (rangetree[rangetree[curr].right].am-rangetree[rangetree[oldcurr].right].am >= am) 
	{
		return treewalk(am, rangetree[curr].right, rangetree[oldcurr].right, mid+1, cend);
	}
	else
	{
		am -= rangetree[rangetree[curr].right].am-rangetree[rangetree[oldcurr].right].am;
		return treewalk(am, rangetree[curr].left, rangetree[oldcurr].left, cstart, mid) + rangetree[rangetree[curr].right].val-rangetree[rangetree[oldcurr].right].val;
	}
}
void dank(int s, int e, int ks, int ke)
{
	if (e < s) return;
	int b = (s+e)/2;
	ll bestans = -1e15;
	ll best = ke;
//	printf("%d - %d %d\n", b, ks, ke);
	for (int i = ks; i <= ke; i++)
	{
		ll am = -1e15;
		if (i-b+1 >= m)
		{
			int oldroot = b == 0 ? 0 : roots[b-1];
			am = treewalk(m, roots[i], oldroot);
			am -= 2*a[i].first;
			am += 2*a[b].first;
			if (am > bestans)
			{
				bestans = am;
				best = i;
			}
		}
	}
//	printf("best %lld (%lld)\n", best, bestans);
	ans = max(ans, bestans);
	dank(s, b-1, ks, best);
	dank(b+1, e, best, ke);
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++)
	{
		scanf("%lld%lld", &a[i].second, &a[i].first);
	}
	sort(a, a+n);
	for (int i = 0; i < n; i++)
	{
		int oldroot = i == 0 ? 0 : roots[i-1];
		roots[i] = ++upto;
		update(a[i].second, roots[i], oldroot);
	}
	dank(0, n-1, 0, n-1);
	printf("%lld\n", ans);
}

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

cake3.cpp: In function 'int main()':
cake3.cpp:85:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d", &n, &m);
  ~~~~~^~~~~~~~~~~~~~~~
cake3.cpp:88:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld%lld", &a[i].second, &a[i].first);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...