이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "aliens.h"
#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define TASK ""
#define bit(x) (1LL << (x))
#define getbit(x, i) (((x) >> (i)) & 1)
#define ALL(x) (x).begin(), (x).end()
using namespace std;
template <typename T1, typename T2> bool mini(T1 &a, T2 b) {
if (a > b) {a = b; return true;} return false;
}
template <typename T1, typename T2> bool maxi(T1 &a, T2 b) {
if (a < b) {a = b; return true;} return false;
}
mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count());
int rand(int l, int r) {
return l + rd() % (r - l + 1);
}
const int N = 2e5 + 5;
const int oo = 1e9;
const long long ooo = 1e18;
const int mod = 1e9 + 7; // 998244353;
const long double pi = acos(-1);
vector <pair <int, long long>> seg;
vector <long double> inter;
vector <int> ind;
pair <int, int> a[N];
long long dp[N];
int cnt[N];
int n,m,k,sz,cur;
typedef long long ll;
long double intersect(pair <int, ll> a, pair <int, ll> b) {
return (long double) (b.se - a.se) / (a.fi - b.fi);
}
bool good(pair <int, ll> a, pair <int, ll> b, pair <int, ll> c) {
long double xM = intersect(a, c);
long double xN = intersect(b, c);
return xM < xN;
}
void addLine(pair <int, ll> s, int i) {
while (sz > 1 && !good(seg[sz - 2], seg[sz - 1], s)) {
seg.pop_back();
inter.pop_back();
ind.pop_back();
sz--;
}
if (sz > 0)
inter.push_back(intersect(s, seg.back()));
seg.push_back(s);
ind.push_back(i);
sz++;
mini(cur, sz - 2);
}
int getopt(int x) {
while (cur + 1 < (int) inter.size() && x >= inter[cur + 1])
cur++;
return cur;
}
int solve(long long cost) {
sz = 0;
inter.clear();
seg.clear();
ind.clear();
inter.push_back(-ooo);
a[n + 1] = mp(oo, oo);
for (int i = 1; i <= n; i++) {
long long add = 1LL * (a[i].se + 1) * (a[i].se + 1);
long long sub = 0;
if (a[i].se >= a[i + 1].fi) {
int d = a[i].se - a[i + 1].fi + 1;
sub = 1LL * d * d;
}
long long y = (dp[i - 1] + 1LL * a[i].fi * a[i].fi) + cost;
int x = -2 * a[i].fi;
addLine(mp(x, y), i - 1);
int it = getopt(a[i].se + 1);
cnt[i] = cnt[ind[it]] + 1;
dp[i] = 1LL * seg[it].fi * (a[i].se + 1) + seg[it].se - sub + add;
}
return cnt[n];
}
long long solve() {
long long lo = -1;
long long hi = 1e12 + 123;
while (hi - lo > 1) {
long long mid = (lo + hi) >> 1;
if (solve(mid) > k)
lo = mid;
else
hi = mid;
}
solve(hi);
return dp[n] - k * hi;
}
void build() {
for (int i = 1; i <= n; i++)
if (a[i].fi > a[i].se)
swap(a[i].fi, a[i].se);
sort(a + 1, a + n + 1, [](pair <int, int> a, pair <int, int> b) {
return (a.fi < b.fi) || (a.fi == b.fi && a.se > b.se);
});
int cur = -oo;
int cnt = 0;
for (int i = 1; i <= n; i++) {
if (a[i].se > cur) {
cur = a[i].se;
a[++cnt] = a[i];
}
}
n = cnt;
}
long long take_photos(int _n, int _m, int _k, vector<int> r, vector<int> c) {
n = _n;
m = _m;
k = _k;
for (int i = 1; i <= n; i++)
a[i] = mp(r[i - 1], c[i - 1]);
build();
return solve();
}
//#include "grader.cpp"
# | 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... |