# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
474256 | evenharder | Aliens (IOI16_aliens) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <iostream>
#include <algorithm>
#include <numeric>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
struct line {
ll a, b, i;
line(ll a=0, ll b=0, ll i=0) : a(a), b(b), i(i) {}
ll calc(ll x) { return a*x+b;}
};
bool check_back(line& p0, line& p1, line& p2) {
return (p1.b - p0.b) * (p1.a - p2.a) >= (p0.a - p1.a) * (p2.b - p1.b);
}
bool check_front(ll x, line& p0, line& p1) {
return x * (p0.a - p1.a) >= (p1.b - p0.b);
}
struct ConvexHull {
size_t apos = 0;
vector<line> v;
void insert(line p) {
while(1) {
size_t sz = v.size();
if(sz >= 2 && check_back(v[sz-2], v[sz-1], p)) {
v.pop_back();
sz--;
}
else break;
}
v.push_back(p);
}
ll query(ll x) {
while(1) {
size_t sz = v.size();
if(sz - apos >= 2 && check_front(x, v[sz-2], v[sz-1]))
apos++;
else break;
}
return v[apos].calc(x);
}
ll track() {
return v.back().i = v.size() - apos == 1 ? 1 : v[apos].i + 1;
}
};
pll take_photos_lambda(vector<pii>& v1, ll eff) {
ConvexHull ch;
ll val = 0, cnt = 0;
for(int i=0;i<v1.size();i++) {
ch.insert(line{-2LL * (v1[i].second-1), val + 1LL * (v1[i].second-1) * (v1[i].second-1)});
val = ch.query(v1[i].first) + v1[i].first * v1[i].first + eff;
cnt = ch.track();
}
return pll{val, cnt};
}
ll take_photos(int n, int m, int k, int* r, int* c) {
vector<pii> v(n), v1;
for(int i=0;i<n;i++) {
v[i] = pii{max(c[i], r[i]), min(c[i], r[i])};
}
sort(v.begin(), v.end());
v.resize(unique(v.begin(), v.end()) - v.begin());
for(int i=0;i<n;i++) {
if(!v1.empty() && v1.back().first == v[i].first) {
continue;
}
if(!v1.empty() && v1.back().second >= v[i].second) {
v1.pop_back();
}
v1.push_back(v[i]);
}
ll leff = 0, reff = 1LL*m*m;
int lind = v1.size(), rind = 1; // decreases when leff increase
while(leff < reff) {
ll meff = (leff + reff) / 2;
pll res = take_photos_lambda(v1, meff);
if(res.second < rind) res.second = rind;
if(res.second > lind) res.second = lind;
if(res.second == k) {
return res.first - k * meff;
}
else if(res.second > k) {
lind = res.second;
leff = meff + 1;
}
else {
rind = res.second;
reff = meff - 1;
}
}
return take_photos_lambda(v1, leff).first - k * leff;
}