제출 #837634

#제출 시각아이디문제언어결과실행 시간메모리
837634erdemkirazAliens (IOI16_aliens)C++17
4 / 100
2 ms340 KiB
#include "aliens.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> ii; const int M = 1e6 + 5; int n, m, k; int at[M]; vector<int> ats; vector<ll> a, b; const ll is_query = -(1LL<<62); struct Line { ll m, b; int cnt; mutable function<const Line*()> succ; bool operator<(const Line& rhs) const { if (rhs.b != is_query) return m < rhs.m; const Line* s = succ(); if (!s) return 0; ll x = rhs.m; return b - s->b < (s->m - m) * x; } }; struct HullDynamic : public multiset<Line> { // will maintain upper hull for maximum bool bad(iterator y) { auto z = next(y); if (y == begin()) { if (z == end()) return 0; return y->m == z->m && y->b <= z->b; } auto x = prev(y); if (z == end()) return y->m == x->m && y->b <= x->b; return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m); } void insert_line(ll m, ll b, int cnt) { m *= -1; b *= -1; auto y = insert({ m, b, cnt }); y->succ = [=] { return next(y) == end() ? 0 : &*next(y); }; if (bad(y)) { erase(y); return; } while (next(y) != end() && bad(next(y))) erase(next(y)); while (y != begin() && bad(prev(y))) erase(prev(y)); } pair<ll, int> eval(ll x) { auto l = *lower_bound((Line) { x, is_query }); return {-(l.m * x + l.b), l.cnt}; } }; vector<int> go; tuple<ll, int, ll> get(ll discourage) { vector<ll> dp(m + 1, 1e18); dp[0] = 0; vector<ll> cost(m + 1); HullDynamic trick; for(int i = 1; i <= m; i++) { ll len = max(0LL, b[i - 1] - a[i]); cost[i] = dp[i - 1] + a[i] * a[i] - len * len; trick.insert_line(- 2 * a[i], cost[i], go[i - 1] + 1); auto [res, cnt] = trick.eval(b[i]); dp[i] = res + b[i] * b[i] + discourage; go[i] = cnt; } // printf("discourage = %.3lf cnt = %d dp = %.3lf real = %lll\n", discourage, cnt, dp[m], ans); ll ans = dp[m] - go[m] * discourage; return {dp[m], go[m], ans}; } ll take_photos(int nn, int mm, int kk, vector<int> rr, vector<int> cc) { n = nn; m = mm; k = kk; for(int i = 0; i < n; i++) { if(rr[i] > cc[i]) { swap(rr[i], cc[i]); } at[rr[i] + 1] = max(at[rr[i] + 1], cc[i] + 2); } a.push_back(0); b.push_back(0); for(int i = 1; i <= m + 1; i++) { if(at[i]) { if(!ats.empty() and ats.back() >= at[i]) { continue; } ats.push_back(at[i]); a.push_back(i); b.push_back(at[i]); } } m = (int) a.size() - 1; k = min(k, m); if(k == 1 or m == 1) { return (b.back() - a[1]) * (b.back() - a[1]); } go.resize(m + 1); ll l = 0, r = 1e13; ll ans = 1e18; while(l < r) { ll m = (l + r) / 2; auto [_, used, res] = get(m); if(used > k) { l = m + 1; } else { ans = min(ans, res); r = m; } } auto [_, used, res] = get(l); ans = res; return ans; }
#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...