Submission #44393

#TimeUsernameProblemLanguageResultExecution timeMemory
44393szawinisAliens (IOI16_aliens)C++17
100 / 100
234 ms65364 KiB
#include "aliens.h"
#include <bits/stdc++.h>
using ll = long long;
using namespace std;

inline ll square(ll x) { return x*x; }

int n, m, k;
vector<ll> l, r;

void tidy_up() {
	for(int i = 0; i < n; i++) if(l[i] > r[i]) swap(l[i], r[i]);
	vector<ll> id(n);
	iota(id.begin(), id.end(), 0);
	sort(id.begin(), id.end(), [] (int i, int j) {
		return make_pair(r[i], -l[i]) < make_pair(r[j], -l[j]);
	});
	vector<ll> tmp;
	tmp.push_back(-1);
	tmp.push_back(id[0]);
	for(int i = 1; i < n; i++) {
		while(tmp.size() > 1 && l[tmp.back()] >= l[id[i]]) tmp.pop_back();
		tmp.push_back(id[i]);
	}
	n = tmp.size() - 1;
	id = tmp;
	for(int i = 1; i <= n; i++) tmp[i] = r[id[i]];
	r = tmp;
	for(int i = 1; i <= n; i++) tmp[i] = l[id[i]];
	l = tmp;
}
struct cht {
	struct line {
		ll m, c;
		int cnt;
		line(ll m, ll c, int cnt): m(m), c(c), cnt(cnt) {};
		ll getVal(ll x) { return m*x + c; }
	};
	vector<line> f;
	int idx;
	bool bad(line l1, line l2, line l3) { // m1 >= m2 >= m3
		assert(l1.m >= l2.m && l2.m >= l3.m);
		return (double) (l1.c-l3.c)*(l2.m-l1.m) <= (double) (l1.c-l2.c)*(l3.m-l1.m);
	}
	void update(ll m, ll c, int cnt) {
		line l = line(m, c, cnt);
		while(f.size() >= 2 && bad(f[f.size()-2], f[f.size()-1], l)) f.pop_back();
		f.push_back(l);
	}
	pair<ll, int> query(ll x) {
		while(idx+1 < f.size() && f[idx+1].getVal(x) < f[idx].getVal(x)) ++idx;
		return make_pair(f[idx].getVal(x), f[idx].cnt);
	}
	void clear() { f.clear(); idx = 0; }
} hull;

pair<ll, int> calc(ll C) {
	vector<pair<ll, int> > dp = vector<pair<ll, int> >(n+1);
	hull.clear();
	dp[0] = {0, 0};
	hull.update(-2*(l[1]-1), square(l[1]-1), 0);
	for(int i = 1; i <= n; i++) {
		auto tmp = hull.query(r[i]);
		dp[i].first = tmp.first + square(r[i]) + C;
		dp[i].second = tmp.second + 1;
		if(i == n) break;
		hull.update(-2*(l[i+1]-1), square(l[i+1]-1) + dp[i].first - square(max(0ll, r[i] - l[i+1] + 1)), dp[i].second);
	}
	return dp[n];
}

ll take_photos(int _n, int _m, int _k, vector<int> _l, vector<int> _r) {
	n = _n, m = _m, k = _k;
	l.resize(n), r.resize(n);
	for(int i = 0; i < n; i++) l[i] = _l[i], r[i] = _r[i];
	tidy_up();
	ll s = 0, e = 1e17;
	while(s < e) {
		ll mid = s+e >> 1;
		if(calc(mid).second <= k) e = mid;
		else s = mid+1;
	}
	return calc(s).first - s * k;
}

Compilation message (stderr)

aliens.cpp: In member function 'std::pair<long long int, int> cht::query(ll)':
aliens.cpp:51:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while(idx+1 < f.size() && f[idx+1].getVal(x) < f[idx].getVal(x)) ++idx;
         ~~~~~~^~~~~~~~~~
aliens.cpp: In function 'll take_photos(int, int, int, std::vector<int>, std::vector<int>)':
aliens.cpp:79:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   ll mid = s+e >> 1;
            ~^~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...