제출 #467502

#제출 시각아이디문제언어결과실행 시간메모리
467502alextodoranAliens (IOI16_aliens)C++17
100 / 100
665 ms9412 KiB
#include <bits/stdc++.h> #define double long double #include "aliens.h" using namespace std; const int N_MAX = 100002; const double E = 0.000001; typedef long long ll; double sq(double x) { return x * x; } int n, m, k; struct Point { int x, y; }; bool operator < (const Point &a, const Point &b) { return make_pair(a.y, -a.x) > make_pair(b.y, -b.x); } Point v[N_MAX]; ll X[N_MAX], Y[N_MAX]; struct Line { double a, b; int index; double eval (double x) { return a * x + b; } }; bool ftest (const Line &l1, const Line &l2, const Line &l3) { return (l2.b - l1.b) * (l2.a - l3.a) < (l3.b - l2.b) * (l1.a - l2.a); } deque <Line> dq; void update (Line l) { while(dq.size() >= 2 && ftest(dq.end()[-2], dq.end()[-1], l) == false) dq.pop_back(); dq.push_back(l); } void query (double x, double &answer, int &index) { while(dq.size() >= 2 && dq[0].eval(x) >= dq[1].eval(x)) dq.pop_front(); answer = dq.front().eval(x); index = dq.front().index; } double dp[N_MAX]; int steps[N_MAX]; void push (int i) { double a = -2 * X[i + 1]; double b = dp[i] + sq(X[i + 1]) - 2 * X[i + 1] - sq(max(0LL, Y[i] - X[i + 1] + 1)); update(Line{a, b, i}); } void compute (double C) { while(!dq.empty()) dq.pop_back(); Y[0] = X[1] - 1; push(0); for(int i = 1; i <= n; i++) { double q; int index; query(Y[i], q, index); dp[i] = sq(Y[i]) + 2 * Y[i] + 1 + C + q; steps[i] = steps[index] + 1; if(i == n) break; push(i); } } ll take_photos(int _n, int _m, int _k, vector <int> _r, vector <int> _c) { n = _n; m = _m; k = _k; for(int i = 1; i <= n; i++) { v[i].x = _r[i - 1]; v[i].y = _c[i - 1]; if(v[i].x > v[i].y) swap(v[i].x, v[i].y); } sort(v + 1, v + n + 1); int posy = 1; Y[1] = v[1].y; X[1] = v[1].x; for(int i = 1; i <= n; i++) if(i > 1 && v[i].y < v[i - 1].y && v[i].x < X[posy]) { posy++; Y[posy] = v[i].y; X[posy] = v[i].x; } n = posy; reverse(X + 1, X + n + 1); reverse(Y + 1, Y + n + 1); double l = 0, r = 1000000000000; int cnt = 64; while(cnt--) { double mid = (l + r) / 2; compute(mid); if(steps[n] > k) l = mid + E; else r = mid; } compute(l); return (ll) round(dp[n] - l * k); }
#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...