Submission #1081180

#TimeUsernameProblemLanguageResultExecution timeMemory
1081180errayAliens (IOI16_aliens)C++17
100 / 100
146 ms6352 KiB
#include "aliens.h" #include <bits/stdc++.h> using namespace std; #ifdef DEBUG #include "/home/ioi/contests/ioi16d2/debug.h" #else #define debug(...) void(37) #endif typedef __int128_t int128_t; struct LineContainer { using E = array<int64_t, 3>; deque<E> d; array<int64_t, 2> pass(E x, E y) { return {y[1] - x[1], x[0] - y[0]}; //It might be already bigger } void add(int64_t m, int64_t c, int info) { E add; add[0] = m, add[1] = c, add[2] = info; while (int(d.size()) > 1) { array<int64_t, 2> isect0 = pass(add, d.back()); array<int64_t, 2> isect1 = pass(d.back(), d.end()[-2]); if (int128_t(isect0[0] * isect1[1]) < int128_t(isect1[0] * isect0[1])) { d.pop_back(); } else { break; } } d.push_back(add); debug(add, d); } int64_t eval_eq(int64_t m, int64_t c, int64_t x) { return m * x + c; } int64_t eval_element(E e, int64_t x) { return eval_eq(e[0], e[1], x); } pair<int64_t, int> eval(int64_t x) { assert(!d.empty()); while (int(d.size()) > 1 && eval_element(d[0], x) > eval_element(d[1], x)) { d.pop_front(); } debug(x, d); return {eval_element(d.front(), x), d.front()[2]}; } }; int64_t S(int x) { return int64_t(x) * x; } long long take_photos(int N, int M, int K, std::vector<int> R_, std::vector<int> C) { vector<array<int, 2>> ranges; for (int i = 0; i < N; ++i) { if (R_[i] - C[i] > 0) { ranges.push_back({C[i], R_[i] + 1}); } else { ranges.push_back({R_[i], C[i] + 1}); } } sort(ranges.begin(), ranges.end(), [&](auto x, auto y) { return array<int, 2>{x[0], -x[1]} < array<int, 2>{y[0], -y[1]}; }); vector<int> L, R; int mx_r = -1; for (auto[l, r] : ranges) { if (mx_r < r) { mx_r = r; L.push_back(l); R.push_back(r); } } debug(N, L, R); N = int(L.size()); K = min(K, N); //cost = best[i][j] + S(R[n] - L[i]) - (n + 1 < N && R[n] > L[n + 1] ? S(R[n] - L[n + 1]) : 0); auto Get = [&](int64_t penalty) { debug(penalty); LineContainer lc; vector<pair<int64_t, int>> ans(N); lc.add(-2 * L[0], S(L[0]), 0); for (int i = 0; i < N; ++i) { ans[i] = lc.eval(R[i]); ans[i].first += + S(R[i]) - (i + 1 < N && R[i] > L[i + 1] ? S(R[i] - L[i + 1]) : 0) + penalty; ans[i].second++; debug(ans[i]); if (i < N - 1) { lc.add(-2 * L[i + 1], ans[i].first + S(L[i + 1]), ans[i].second); } } debug(ans); return ans[N - 1]; }; int64_t low = 0, high = int64_t(M) * M; while (low < high) { int64_t mid = (low + high) >> 1; if (Get(mid).second > K) { low = mid + 1; } else { high = mid; } } auto[r, k] = Get(low); debug(low, r, k); r -= 1LL * low * K; return r; }
#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...