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"
#define ll long long
#define pii array<ll,2>
#define tii array<ll,3>
#include <bits/stdc++.h>
using namespace std;
struct Event {
int pos;
int other;
bool isStart = true;
int idx=0;
bool operator<(const Event &x) {
if (pos != x.pos) return pos < x.pos;
if (idx != x.idx) return !isStart;
return isStart;
}
};
vector<pii> compress(vector<pii> x) {
vector<pii> ret;
for (auto y:x) {
while (ret.size() && ret.back()[0] == y[0]) ret.pop_back();
ret.push_back(y);
}
// now remove all with same ending positions
for (auto &x:ret) swap(x[0], x[1]);
sort(ret.begin(), ret.end());
vector<pii> fr;
for (auto &y:ret) {
swap(y[0], y[1]);
if (fr.size() && fr.back()[1] == y[1]) continue;
fr.push_back(y);
}
sort(fr.begin(), fr.end());
return fr;
}
void rec(int j, int l, int r, vector<vector<ll>> &dp, vector<pii> &intv, int optl, int optr) {
if (l > r) return;
int m = (l+r)/2;
int opt = -1;
dp[m][j] = dp[m][j-1];
for (int k=optl;k<=min(optr, m);k++) {
ll cur = (k > 0 ? dp[k-1][j-1] : 0);
ll cost = (intv[m][1] - intv[k][0] + 1) * (intv[m][1] - intv[k][0] + 1);
if (k > 0 && intv[k-1][1] >= intv[k][0]) {
cost -= (intv[k-1][1] - intv[k][0] + 1) * (intv[k-1][1] - intv[k][0] + 1);
}
cur += cost;
if (cur <= dp[m][j]) {
opt = k;
dp[m][j] = cur;
}
}
rec(j, l, m-1, dp, intv, optl, opt);
rec(j, m+1, r, dp, intv, opt, optr);
}
long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) {
for (int i=0;i<n;i++) {
if (r[i] < c[i])swap(r[i], c[i]);
}
vector<pii> intv(n);
for (int i=0;i<n;i++) {
intv[i]={c[i], r[i]};
}
sort(intv.begin(), intv.end());
intv.erase(unique(intv.begin(), intv.end()), intv.end());
intv = compress(intv);
vector<Event> vv;
int tmp=0;
for (auto &x:intv) {
Event e1;e1.pos=x[0];e1.other=x[1];e1.idx=tmp++;
vv.push_back(e1);
swap(e1.pos, e1.other);e1.isStart=false;
vv.push_back(e1);
}
sort(vv.begin(), vv.end());
multiset<int> starts;
vector<bool> ers(intv.size(), false);
for (auto &x:vv) {
if (x.isStart) {
starts.insert(x.pos);
}
else {
starts.erase(starts.find(x.other));
if (starts.size()) {
int mn = *starts.begin();
if (mn < x.other) ers[x.idx]=true;
}
}
}
vector<pii> newInvs;
for (int i=0;i<(int)intv.size();i++) {
if (ers[i]) continue;
newInvs.push_back(intv[i]);
}
intv = newInvs;
n = (int)intv.size();
k = min(k, n);
vector<vector<ll>> dp(n, vector<ll>(k, 1e18));
for (int i=0;i<n;i++) {
dp[i][0] = (intv[i][1] - intv[0][0] + 1) * (intv[i][1] - intv[0][0] + 1);
}
for (int j=1;j<k;j++) {
rec(j, 0, n-1, dp, intv, 0, n);
}
// for (auto &x:dp) {
// for (ll y:x) {
// cout << y << " ";
// }
// cout << "\n";
// }
return dp[n-1][k-1];
}
# | 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... |