Submission #1227772

#TimeUsernameProblemLanguageResultExecution timeMemory
1227772madamadam3Aliens (IOI16_aliens)C++20
100 / 100
1016 ms161256 KiB
#include "aliens.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; using vi = vector<int>; using vvi = vector<vi>; using vl = vector<ll>; using vvl = vector<vl>; const ll INF = 1e18; int n, m, k; vl r, c, L, R; void preprocess(int N, int M, int K, vi Row, vi Col) { vector<int> sorted_points(N); iota(sorted_points.begin(), sorted_points.end(), 0); sort(sorted_points.begin(), sorted_points.end(), [&](int a, int b) { ll La = min(Row[a], Col[a]), Ra = max(Row[a], Col[a]), Lb = min(Row[b], Col[b]), Rb = max(Row[b], Col[b]); return La == Lb ? Ra > Rb : La < Lb; }); vector<int> points; int lastR = -1; for (int i = 0; i < N; i++) { int cur = sorted_points[i]; int rcur = max(Row[cur], Col[cur]); if (rcur > lastR) { points.push_back(cur); lastR = rcur; } } n = points.size(); m = M; k = K; r.resize(n); c.resize(n); L.resize(n); R.resize(n); for (int i = 0; i < n; i++) { r[i] = Row[points[i]]; c[i] = Col[points[i]]; L[i] = min(r[i], c[i]); R[i] = max(r[i], c[i]); } } struct Function { ll b, c; ll seg; Function(ll B = 0, ll C = INF, ll s = 0) : b(B), c(C), seg(s) {}; ll evaluate(ll x) { return x*x + b*x + c; } }; bool better(Function& f1, Function& f2, ll x) { ll v1 = f1.evaluate(x), v2 = f2.evaluate(x); if (v1 != v2) return v1 < v2; return f1.seg < f2.seg; } struct Node { Function best; Node *left, *right; Node() : best(Function()), left(nullptr), right(nullptr) {}; Node(Function Best) : best(Best), left(nullptr), right(nullptr) {}; }; // implicit segtree storing minimum function at x for x in [0, 1m] struct LiChaoTree { int lower, upper; Node* root; LiChaoTree() {}; LiChaoTree(int L, int U) { lower = L; upper = U; root = new Node(); } Node* update(Node* cur, int l, int r, Function fnew) { if (!cur) cur = new Node(); int m = l + (r - l) / 2; if (better(fnew, cur->best, m)) swap(cur->best, fnew); if (better(fnew, cur->best, l)) cur->left = update(cur->left, l, m, fnew); else if (better(fnew, cur->best, r)) cur->right = update(cur->right, m, r, fnew); return cur; } pair<ll, ll> query(Node* cur, int l, int r, ll x) { if (!cur) return {INF, 0}; pair<ll, ll> our_val = {cur->best.evaluate(x), cur->best.seg}; if (l + 1 == r) return our_val; int m = l + (r - l) / 2; if (x < m) return min(our_val, query(cur->left, l, m, x)); else return min(our_val, query(cur->right, m, r, x)); } void update(Function fnew) { update(root, lower, upper+1, fnew); } pair<ll, ll> query(ll x) { return query(root, lower, upper+1, x); } }; void compute_dp(ll lambda, vl& dp, vl &cnt, const vl &overlap) { dp.assign(n, INF); cnt.assign(n, 0); LiChaoTree lct(0, m+1); ll L0 = L[0] - 1; lct.update(Function(-2*L0, L0*L0 + lambda, 1)); auto r0 = lct.query(R[0]); dp[0] = r0.first; cnt[0] = r0.second; for (int i = 1; i < n; ++i) { ll Lj = L[i] - 1; ll B = -2 * Lj; ll C = dp[i-1] + Lj*Lj + lambda - overlap[i]; int nseg = cnt[i-1] + 1; lct.update(Function(B, C, nseg)); auto res = lct.query(R[i]); dp[i] = res.first; cnt[i] = res.second; } } ll take_photos(int N, int M, int K, vi Row, vi Col) { preprocess(N, M, K, Row, Col); vl overlap(n, 0); for (int i = 1; i < n; i++) { ll over = max(0LL, R[i-1] - L[i] + 1); over *= over; overlap[i] = over; } ll lo = 0, hi = 1e13; vector<ll> dp, cnt; while (lo < hi) { ll mid = (lo + hi) >> 1; compute_dp(mid, dp, cnt, overlap); if (cnt.back() > k) lo = mid + 1; else hi = mid; } compute_dp(lo, dp, cnt, overlap); return dp.back() - 1LL * lo * k; }

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...