제출 #712318

#제출 시각아이디문제언어결과실행 시간메모리
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...