Submission #299040

#TimeUsernameProblemLanguageResultExecution timeMemory
299040SeDunionAliens (IOI16_aliens)C++17
100 / 100
670 ms12292 KiB
#include "aliens.h" #include <bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; const int N = 1e6 + 123; const ll INF = 1e18; const ll inf = 1e10; const ld eps = 1e-12; ll x[N], y[N]; ll sq (ll x) { return x * x; } struct line { ll k, b; int cnt; ll f (ll x) { return k * x + b; } }; ld inter (line a, line b) { return ld(b.b - a.b) / ld(a.k - b.k); } struct cht { vector<line> v; void add (line a) { while (v.size() > 1 && inter (v.back(), v[v.size() - 2]) > inter (v[v.size() - 2], a)) { v.pop_back(); } v.push_back (a); } pair<ll,int> get (ll x) { if (v.empty()) return {-INF, 0}; int l = 0, r = int(v.size()) - 2; pair<ll,int> ans = {v.back().f(x), -v.back().cnt}; while (l <= r) { int m = (l + r) >> 1; ans = max (ans, {v[m].f(x), -v[m].cnt}); if (inter (v[m], v[m + 1]) < x) { l = m + 1; } else { r = m - 1; } } if (l < (int)v.size()) ans = max (ans, {v[l].f(x), -v[l].cnt}); if (r >= 0) ans = max (ans, {v[r].f(x), -v[r].cnt}); return {ans.first, ans.second * -1}; } }; pair<ll,int> calc (int n, int m, int k, ll hph) { vector<ll> dp(n + 1, INF); vector<int> cnt(n + 1, -1); cht ok; // cout << hph << " hph\n"; for (int i = 1 ; i <= n ; ++ i) { ok.add ({2 * x[i], -dp[i - 1] - sq(x[i]) + 2 * x[i] - 1 + sq(max(0ll,y[i-1]-x[i]+1)), cnt[i-1]}); auto gt = ok.get (y[i]); dp[i] = sq(y[i]) + 2 * y[i] - gt.first + hph; cnt[i] = gt.second + 1; // cout << gt.first << " " << gt.second << " " << dp[i] << " "; if (dp[i] > sq(y[i] - x[1] + 1) + hph) { dp[i] = sq(y[i] - x[1] + 1) + hph; cnt[i] = 1; } // cout << dp[i] << " " << cnt[i] << "\n"; } return {dp[n], cnt[n]}; } ll take_photos(int n, int m, int k, vector<int> r, vector<int> c) { vector<pair<int,int>> a(n); for (int i = 0 ; i < n ; ++ i) { if (r[i] > c[i]) swap (r[i], c[i]); a[i] = {r[i], c[i]}; } sort (a.begin(), a.end()); int n_ = 0; for (int i = 0, ymx = -1 ; i < n ; ++ i) { bool rm = false; if (i + 1 < n && a[i].first == a[i + 1].first) { rm = true; } if (a[i].second <= ymx) { rm = true; } if (!rm) { ++n_; x[n_] = a[i].first; y[n_] = a[i].second; } if (i + 1 > n || a[i].first != a[i + 1].first) ymx = max (ymx, a[i].second); } n = n_; k = min (n, k); { ll l = 0, r = m*1ll*m; ll res = -1; while (l <= r) { ll hph = (l + r) / 2; auto now = calc (n, m, k, hph); if (now.second > k) { l = hph + 1; } else { res = hph; r = hph - 1; } } auto now = calc (n, m, k, res); //cout << now.first << " " << now.second << " " << l << "\n"; return now.first - 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...