Submission #102617

#TimeUsernameProblemLanguageResultExecution timeMemory
102617hugo_pmCake 3 (JOI19_cake3)C++17
100 / 100
2417 ms19780 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= b; --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const long long BIG = 1000000000000000000LL;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void cpr(string s, vector<int> v)
{ int i = 0; for (char c : s) { if (c == '$') cout << v[i++]; else cout << c; } cout << '\n'; }

void cpr(string s) { cpr(s, {}); }

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

const int borne = 201*1000;
int nbPieces, nbVoulu;
pii pieces[borne];
int rep = -BIG;

pii st[4*borne];
int otn[borne];
int gt[borne];

void upd(int nod, int il, int ir, int cible, int val)
{
	if (il == ir) {
		assert(il == cible);
		st[nod].fi += val*otn[il];
		st[nod].se += val;
		return;
	}
	int im = (il+ir)/2;
	if (cible <= im) upd(2*nod, il, im, cible, val);
	else upd(2*nod+1, im+1, ir, cible, val);
	st[nod].fi = st[2*nod].fi + st[2*nod+1].fi;
	st[nod].se = st[2*nod].se + st[2*nod+1].se;
}

int cl=0, cr=0;
pii walk(int nod, int il, int ir, int k)
{
	if (k == 0 || st[nod].se == 0) return {0,0};
	if (st[nod].se <= k) {
		return st[nod];
	}
	int im = (il+ir)/2;
	pii ret = walk(2*nod+1, im+1, ir, k);
	k -= ret.se;
	pii ret2 = walk(2*nod, il, im, k);
	ret.fi += ret2.fi;
	ret.se += ret2.se;
	return ret;
}

int func(int deb, int fin)
{
	if (fin < deb+nbVoulu-1) return -BIG;
	int ca = 2*(pieces[deb].fi - pieces[fin].fi);
	int nod = 1;

	while (cl < deb) { upd(nod, 0, nbPieces-1, gt[cl], -1); ++cl; } // suppr
	while (cl > deb) { --cl; upd(nod, 0, nbPieces-1, gt[cl], 1); } // rajout
	while (cr > fin) { upd(nod, 0, nbPieces-1, gt[cr], -1); --cr; } // suppr
	while (cr < fin) { ++cr; upd(nod, 0, nbPieces-1, gt[cr], 1); } // rajout

	assert(st[1].se == (fin-deb+1));
	ca += walk(nod, 0, nbPieces-1, nbVoulu).fi;
	return ca;
}

void calc(int il, int ir, int kl, int kr)
{
	if (il > ir) return;
	int im = (il+ir) / 2;
	int ca = -BIG-1, opt = kl;
	form2(k, kl, min(kr, ir)+1) {
		int nv = func(k, im);
		if (nv > ca) {
			ca = nv;
			opt = k;
		}
	}

	chmax(rep, ca);
	calc(il, im-1, kl, opt);
	calc(im+1, ir, opt, kr);
}

map<int, int> nto;

void solve()
{
	cin >> nbPieces >> nbVoulu;
	form(i, nbPieces) {
		// val, coul
		cin >> pieces[i].fi >> pieces[i].se; 
	}
	sort(pieces, pieces+nbPieces);
	vector<pair<pii, int>> oth;
	form(i, nbPieces) {
		// devient coul, val
		swap(pieces[i].fi, pieces[i].se);
		oth.push_back({pieces[i], i});
	}
	sort(oth.begin(), oth.end());
	sort(pieces, pieces+nbPieces);
	form(i, nbPieces) { gt[i] = oth[i].se; otn[gt[i]] = pieces[i].se; }
	sort(pieces, pieces+nbPieces);
	upd(1, 0, nbPieces-1, gt[0], 1);
	calc(0, nbPieces-1, 0, nbPieces-1);
	cout << rep << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...