This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = (ll)1e18;
ll ccw (pair<ll,ll> p1, pair<ll,ll> p2, pair<ll,ll> p3) {
return (p2.first-p1.first)*(p3.second-p2.second) - (p2.second-p1.second)*(p3.first-p2.first);
}
struct Hull {
vector<pair<ll,ll>> hull; ll p = 0;
void insert(pair<ll,ll> p) { //points inserted with increasing x
// if (hull.size()) assert(p.first >= hull.back().first);
while (hull.size() >= 2 && ccw(hull[hull.size()-2],hull.back(),p) < 0) hull.pop_back();
hull.push_back(p);
}
ll query(ll k) { //minimise y-kx
while (p < hull.size()-1 && -k*hull[p].first + hull[p].second > -k*hull[p+1].first + hull[p+1].second) p++;
return -k*hull[p].first + hull[p].second;
// ll low = INF;
// for (auto p: hull) low = min(low,-k*p.first+p.second);
// return low;
}
};
ll take_photos(int n, int m, int k, vector<int> ri, vector<int> ci) {
vector<pair<ll,ll>> points;
for (int i = 0; i < n; i++) points.push_back(make_pair(max(ci[i],ri[i]),min(ri[i],ci[i])));
sort(points.begin(),points.end());
vector<ll> r,c; //such that r_i < r_j, c_i < c_j
for (int i = 0; i < n; i++) {
while (r.size() > 0 && points[i].second <= r.back()) {
r.pop_back(); c.pop_back();
}
r.push_back(points[i].second); c.push_back(points[i].first);
}
n = r.size();
// for (int i = 0; i < n; i++) cout << r[i] << " " << c[i] << "\n";
vector<vector<ll>> dp(k+1, vector<ll> (n+1,INF)); //dp[k][i] = min squares covered over the first i points, using k segments
vector<Hull> hulls(k+1);
for (int u = 0; u <= k; u++) {
dp[u][0] = 0;
hulls[u].insert(make_pair(2*r[0],r[0]*r[0]-2*r[0]));
}
for (int i = 1; i <= n; i++) {
for (int u = 1; u <= k; u++) {
dp[u][i] = (c[i-1]+1)*(c[i-1]+1) + hulls[u-1].query(c[i-1]);
ll overlap;
if (c[i-1] < r[i]) overlap = 0LL;
else overlap = (c[i-1]-r[i]+1)*(c[i-1]-r[i]+1);
if (i < n) hulls[u].insert(make_pair(2*r[i],dp[u][i] + r[i]*r[i]-2*r[i]-overlap));
}
}
return dp[k][n];
}
// int main() {
// Hull test;
// test.insert({3,4});
// test.insert({3,4});
// test.insert({5,1});
// cout << test.query(0) << "\n";
// }
Compilation message (stderr)
aliens.cpp: In member function 'll Hull::query(ll)':
aliens.cpp:21:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while (p < hull.size()-1 && -k*hull[p].first + hull[p].second > -k*hull[p+1].first + hull[p+1].second) p++;
~~^~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |