제출 #44393

#제출 시각아이디문제언어결과실행 시간메모리
44393szawinisAliens (IOI16_aliens)C++17
100 / 100
234 ms65364 KiB
#include "aliens.h" #include <bits/stdc++.h> using ll = long long; using namespace std; inline ll square(ll x) { return x*x; } int n, m, k; vector<ll> l, r; void tidy_up() { for(int i = 0; i < n; i++) if(l[i] > r[i]) swap(l[i], r[i]); vector<ll> id(n); iota(id.begin(), id.end(), 0); sort(id.begin(), id.end(), [] (int i, int j) { return make_pair(r[i], -l[i]) < make_pair(r[j], -l[j]); }); vector<ll> tmp; tmp.push_back(-1); tmp.push_back(id[0]); for(int i = 1; i < n; i++) { while(tmp.size() > 1 && l[tmp.back()] >= l[id[i]]) tmp.pop_back(); tmp.push_back(id[i]); } n = tmp.size() - 1; id = tmp; for(int i = 1; i <= n; i++) tmp[i] = r[id[i]]; r = tmp; for(int i = 1; i <= n; i++) tmp[i] = l[id[i]]; l = tmp; } struct cht { struct line { ll m, c; int cnt; line(ll m, ll c, int cnt): m(m), c(c), cnt(cnt) {}; ll getVal(ll x) { return m*x + c; } }; vector<line> f; int idx; bool bad(line l1, line l2, line l3) { // m1 >= m2 >= m3 assert(l1.m >= l2.m && l2.m >= l3.m); return (double) (l1.c-l3.c)*(l2.m-l1.m) <= (double) (l1.c-l2.c)*(l3.m-l1.m); } void update(ll m, ll c, int cnt) { line l = line(m, c, cnt); while(f.size() >= 2 && bad(f[f.size()-2], f[f.size()-1], l)) f.pop_back(); f.push_back(l); } pair<ll, int> query(ll x) { while(idx+1 < f.size() && f[idx+1].getVal(x) < f[idx].getVal(x)) ++idx; return make_pair(f[idx].getVal(x), f[idx].cnt); } void clear() { f.clear(); idx = 0; } } hull; pair<ll, int> calc(ll C) { vector<pair<ll, int> > dp = vector<pair<ll, int> >(n+1); hull.clear(); dp[0] = {0, 0}; hull.update(-2*(l[1]-1), square(l[1]-1), 0); for(int i = 1; i <= n; i++) { auto tmp = hull.query(r[i]); dp[i].first = tmp.first + square(r[i]) + C; dp[i].second = tmp.second + 1; if(i == n) break; hull.update(-2*(l[i+1]-1), square(l[i+1]-1) + dp[i].first - square(max(0ll, r[i] - l[i+1] + 1)), dp[i].second); } return dp[n]; } ll take_photos(int _n, int _m, int _k, vector<int> _l, vector<int> _r) { n = _n, m = _m, k = _k; l.resize(n), r.resize(n); for(int i = 0; i < n; i++) l[i] = _l[i], r[i] = _r[i]; tidy_up(); ll s = 0, e = 1e17; while(s < e) { ll mid = s+e >> 1; if(calc(mid).second <= k) e = mid; else s = mid+1; } return calc(s).first - s * k; }

컴파일 시 표준 에러 (stderr) 메시지

aliens.cpp: In member function 'std::pair<long long int, int> cht::query(ll)':
aliens.cpp:51:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while(idx+1 < f.size() && f[idx+1].getVal(x) < f[idx].getVal(x)) ++idx;
         ~~~~~~^~~~~~~~~~
aliens.cpp: In function 'll take_photos(int, int, int, std::vector<int>, std::vector<int>)':
aliens.cpp:79:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   ll mid = s+e >> 1;
            ~^~
#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...