Submission #739518

#TimeUsernameProblemLanguageResultExecution timeMemory
739518boris_mihovAliens (IOI16_aliens)C++17
100 / 100
135 ms6832 KiB
#include "aliens.h" #include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <vector> #include <queue> typedef long long llong; const int MAXN = 100000 + 10; const int INF = 1e9; int n, m, k; struct Interval { int l, r; inline friend bool operator < (const Interval &a, const Interval &b) { return a.l < b.l || (a.l == b.l && a.r < b.r); } }; struct CHT { struct Line { llong x, y; int cntPenalties; int to; std::pair <llong,int> getValue(int at) { return {x * at + y, cntPenalties}; } }; llong intersect(Line a, Line b) { if (a.y >= b.y) { return INF; } return (b.y - a.y) / (a.x - b.x) - ((b.y - a.y) % (a.x - b.x) == 0 && b.cntPenalties < a.cntPenalties); } std::deque <Line> dq; void reset() { dq.clear(); } void push(Line toPush) { while (dq.size() && dq.front().getValue(dq.front().to) > toPush.getValue(dq.front().to)) { dq.pop_front(); } if (dq.empty()) { dq.push_front(toPush); } else { llong where = intersect(toPush, dq.front()); if (where <= m) dq.push_front({toPush.x, toPush.y, toPush.cntPenalties, where}); } } std::pair <llong,int> find(int at) { while (dq.size() >= 2 && dq[dq.size() - 2].to >= at) { dq.pop_back(); } assert(dq.size()); return dq.back().getValue(at); } }; CHT cht; std::vector <Interval> v; std::pair <llong,int> dp[MAXN]; std::pair <llong,int> check(llong penalty) { cht.reset(); cht.push({-2 * v.back().r, 1LL * v.back().r * v.back().r + penalty, 1, m}); for (int idx = v.size() - 1 ; idx >= 0 ; --idx) { dp[idx] = cht.find(v[idx].l); dp[idx].first += 1LL * v[idx].l * v[idx].l; if (idx != 0) { llong toRemove = std::max(0, v[idx - 1].r - v[idx].l); toRemove *= toRemove; cht.push({-2 * v[idx - 1].r, 1LL * v[idx - 1].r * v[idx - 1].r + dp[idx].first - toRemove + penalty, dp[idx].second + 1, m}); } } return dp[0]; } llong take_photos(int N, int M, int K, std::vector <int> x, std::vector <int> y) { n = N; m = M; k = K; std::vector <Interval> sorted; for (int i = 0 ; i < n ; ++i) { sorted.push_back({std::min(x[i], y[i]), std::max(x[i], y[i]) + 1}); } std::sort(sorted.begin(), sorted.end()); for (const Interval &curr : sorted) { while (v.size() && v.back().l == curr.l && curr.r >= v.back().r) { v.pop_back(); } if (v.empty() || v.back().r < curr.r) { v.push_back(curr); } } k = std::min(k, (int)v.size()); llong l = -1, r = 1LL * m * m, mid; while (l < r - 1) { mid = (l + r) / 2; auto res = check(mid); if (res.second == k) { return res.first - k * mid; } if (res.second > k) l = mid; else r = mid; } auto resL = check(l); auto resR = check(r); llong fL = resL.first - resL.second * l; llong fR = resR.first - resR.second * r; return fL + (fR - fL) * (resL.second - k) / (resL.second - resR.second); }

Compilation message (stderr)

aliens.cpp: In member function 'void CHT::push(CHT::Line)':
aliens.cpp:66:85: warning: narrowing conversion of 'where' from 'llong' {aka 'long long int'} to 'int' [-Wnarrowing]
   66 |             if (where <= m) dq.push_front({toPush.x, toPush.y, toPush.cntPenalties, where});
      |                                                                                     ^~~~~
#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...