Submission #712318

#TimeUsernameProblemLanguageResultExecution timeMemory
712318SanguineChameleonAliens (IOI16_aliens)C++17
100 / 100
201 ms14212 KiB
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 20;
const long long inf = 1e18L + 20;
const long long max_cost = 1e12L + 20;
long long lt[maxn];
long long rt[maxn];
long long over[maxn];
pair<long long, int> dp[maxn];
long long cost;
int n;

struct line {
	long long a, b;
	int cnt;

	line(long long _a, long long _b, int _cnt): a(_a), b(_b), cnt(_cnt) {};

	long long eval(long long x) {
		return a * x + b;
	};
};

long long fdiv(long long x, long long y) {
	return (x / y) - ((x ^ y) < 0 && (x > y));
}

long long inter(line L1, line L2) {
	return fdiv(L1.b - L2.b, L2.a - L1.a);
}

struct CHT {
	vector<line> Q;
	int pt = 0;

	void add(line L) {
		while ((int)Q.size() >= 2 && inter(L, Q.back()) <= inter(Q.back(), Q.end()[-2])) {
			Q.pop_back();
		}
		Q.push_back(L);
	}

	pair<long long, int> get(long long x) {
		pt = min(pt, (int)Q.size());
		while (pt + 1 < (int)Q.size() && Q[pt].eval(x) > Q[pt + 1].eval(x)) {
			pt++;
		}
		return {Q[pt].eval(x) + x * x, Q[pt].cnt + 1};
	}
};

void solve() {
	CHT C;
	dp[0] = {0, 0};
	C.add(line(2 - lt[1] * 2, lt[1] * lt[1] - lt[1] * 2 + cost + 1, 0));
	for (int i = 1; i <= n; i++) {
		dp[i] = C.get(rt[i]);
		C.add(line(2 - lt[i + 1] * 2, dp[i].first + lt[i + 1] * lt[i + 1] - lt[i + 1] * 2 - over[i] + cost + 1, dp[i].second));
	}
}

long long take_photos(int _n, int m, int k, std::vector<int> rows, std::vector<int> cols) {
	n = _n;
	vector<pair<int, int>> p, q;
	for (int i = 0; i < n; i++) {
		if (rows[i] > cols[i]) {
			swap(rows[i], cols[i]);
		}
		p.push_back({rows[i], -cols[i]});
	}
	sort(p.begin(), p.end());
	for (auto x: p) {
		if (q.empty() || x.second < q.back().second) {
			q.push_back(x);
		}
	}
	n = q.size();
	k = min(k, n);
	for (int i = 0; i < n; i++) {
		lt[i + 1] = q[i].first;
		rt[i + 1] = -q[i].second;
	}
	over[0] = 0;
	for (int i = 1; i <= n - 1; i++) {
		long long sz = max(rt[i] - lt[i + 1] + 1, 0LL);
		over[i] = sz * sz;
	}
	long long cost_l = 0;
	long long cost_r = max_cost;
	long long res = inf;
	while (cost_l <= cost_r) {
		cost = (cost_l + cost_r) / 2;
		solve();
		if (dp[n].second <= k) {
			res = dp[n].first - cost * k;
			cost_r = cost - 1;
		}
		else {
			cost_l = cost + 1;
		}
	}
	return res;
}
#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...