Submission #1198801

#TimeUsernameProblemLanguageResultExecution timeMemory
1198801ericl23302Aliens (IOI16_aliens)C++20
100 / 100
151 ms11068 KiB
#include "aliens.h" #include <iostream> #include <algorithm> #include <utility> #include <climits> #include <complex> // using namespace std; // using ll = long long; // typedef complex<ll> point; // #define x real // #define y imag // ll sq(ll a) { // return a * a; // } // ll sq(int a) { // return (ll)(a) * a; // } // // ll getArea(pair<ll, ll> a) { // // return sq(a.second - a.first + 1); // // } // // ll getArea(ll a, ll b) { // // return sq(b - a + 1); // // } // ll positiveArea(ll a, ll b) { // ll sideLength = b - a + 1; // return (sideLength > 0 ? sq(sideLength) : 0); // } // ll dot(point a, point b) { // return ((conj(a) * b).x()); // } // ll cross(point a, point b) { // return ((conj(a) * b).y()); // } // vector<point> hull, vec; // vector<ll> countHull; // void addLine(ll m, ll c, ll count) { // point newLine({m, c}); // while (!vec.empty() && (dot(vec.back(), newLine - hull.back()) < 0)) { // vec.pop_back(); // hull.pop_back(); // countHull.pop_back(); // } // if (!hull.empty()) vec.push_back(point({0, 1}) * (newLine - hull.back())); // countHull.push_back(count); // hull.push_back(newLine); // } // pair<ll, ll> query(ll ri) { // point toFind({ri, 1}); // ll idx = lower_bound(vec.begin(), vec.end(), toFind, [](point a, point b) {return (cross(a, b) > 0);}) - vec.begin(); // return {dot(toFind, hull[idx]), countHull[idx]}; // } // ll take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) { // vector<pair<ll, ll>> oriPoints, points; // for (ll i = 0; i < n; ++i) { // if (r[i] > c[i]) swap(r[i], c[i]); // oriPoints.emplace_back(r[i], c[i]); // } // sort(oriPoints.begin(), oriPoints.end()); // pair<ll, ll> cur = oriPoints[0]; // for (ll i = 1; i < n; ++i) { // if (oriPoints[i].first == cur.first) cur.second = max(oriPoints[i].second, cur.second); // else if (cur.second < oriPoints[i].second) { // if (cur.first != -1) points.emplace_back(cur); // cur = oriPoints[i]; // } // } // points.emplace_back(cur); // int newN = points.size(); // auto check = [&] (ll cost, ll &res) { // hull.clear(); vec.clear(); countHull.clear(); // vector<ll> dp(newN + 1, 0), counts(newN + 1, 0); // for (int i = 1; i <= newN; ++i) { // ll m = 2 * (points[i - 1].first - 1), c = sq(points[i - 1].first - 1) + dp[i - 1] + (i > 1 ? positiveArea(points[i - 1].first, points[i - 2].second) : 0); // addLine(m, c, counts[i - 1]); // auto cur = query(-points[i - 1].second); // dp[i] = cur.first + cost + sq(points[i - 1].second); // counts[i] = cur.second + 1; // } // res = dp[newN]; // return (counts[newN] <= k); // }; // ll low = 0, high = sq(m), res = LLONG_MAX / 2; // while (low < high) { // ll mid = (low + high) / 2; // if (check(mid, res)) high = mid; // else low = mid + 1; // } // check(low, res); // return (res - k * low); // } using namespace std; typedef long long ll; typedef std::complex<ll> point; #define x real #define y imag const ll INF = 1e18; ll dot(point a, point b) { return (std::conj(a) * b).x(); } ll cross(point a, point b) { return (std::conj(a) * b).y(); } std::vector<point> hull, vecs; std::vector<int> cnth; void add_line(ll slope, ll y_intercept, int cnt) { point new_line({slope, y_intercept}); while(!vecs.empty() && dot(vecs.back(), new_line - hull.back()) < 0) { hull.pop_back(); vecs.pop_back(); cnth.pop_back(); } if(!hull.empty()) { vecs.push_back(point({0, 1}) * (new_line - hull.back())); } hull.push_back(new_line); cnth.push_back(cnt); } pair<ll, int> get(ll x_value) { point to_query = point({x_value, 1}); int index = lower_bound(vecs.begin(), vecs.end(), to_query, [](point a, point b) { return cross(a, b) > 0; }) - vecs.begin(); ll val = dot(to_query, hull[index]); int mx = cnth[index]; return {val, mx}; } long long take_photos(int n, int m, int k, std::vector<int> rr, std::vector<int> cc) { vector<array<int, 2>> intervals; for(int i = 0; i < n; i++) { if(rr[i] > cc[i]) swap(rr[i], cc[i]); intervals.push_back({rr[i], cc[i]}); } sort(intervals.begin(), intervals.end(), [](array<int, 2> a, array<int, 2> b) { if(a[0] == b[0]) return a[1] > b[1]; return a[0] < b[0]; }); vector<array<int, 2>> intervals2; vector<ll> l, r; for(int i = 0; i < n; i++) { if(i == 0 || intervals[i][0] < intervals2.back()[0] || intervals[i][1] > intervals2.back()[1]) { intervals2.push_back(intervals[i]); l.push_back(intervals[i][0]); r.push_back(intervals[i][1]); } } n = intervals2.size(); auto works = [&](ll lambda, ll& ans) { hull.clear(); vecs.clear(); cnth.clear(); // cout << lambda << '\n'; vector<ll> dp(n + 1); vector<int> cnt(n + 1); for(int i = 1, j = 0; i <= n; i++, j++) { ll slope = 2 * (l[j] - 1); ll intercept = ((l[j] - 1) * (l[j] - 1) + dp[j]); // cout << slope << ' ' << intercept << ' '; if(j > 0) { ll mx = max(0LL, r[j - 1] - l[j] + 1); intercept -= mx * mx; } add_line(slope, intercept, cnt[j]); auto gg = get(-r[j]); dp[i] = gg.first + r[j] * r[j] + lambda; cnt[i] = gg.second + 1; // cout << dp[i] << ' ' << cnt[i] << '\n'; } ans = dp[n]; return cnt[n] <= k; }; ll lo = 0, hi = 1LL * m * m, ans = INF; while(lo < hi) { ll mid = lo + (hi - lo) / 2; if(works(mid, ans)) { hi = mid; } else { lo = mid + 1; } } works(hi, ans); return ans - k * hi; }

Compilation message (stderr)

aliens.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
aliens_c.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
#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...