# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1255759 | allin27x | Aliens (IOI16_aliens) | C++20 | 0 ms | 0 KiB |
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define _min(x,y) x = min(x,y)
const int INF = 1e18;
const int N = 1e5+4;
int dp[N][2];
int sm[N];
struct line {
int a=0,b=0;
int f(int x) {
return a*x + b;
}
};
const int M = 1e6+4;
line T[4*M];
void add(int l, int r, int p, line &nw) {
int m = (l+r)/2;
int c1 = nw.f(m) <= T[p].f(m); int c2 = nw.f(l) <= T[p].f(l);
if (c1) swap(T[p], nw);
if (l == r) return;
if (c1^c2) add(l, m, 2*p+1, nw); else add(m+1, r, 2*p+2, nw);
}
int ans(int l, int r, int p, int pt) {
int m = (l+r)/2;
if (l == r) return T[p].f(pt);
if (pt <= m) return min(T[p].f(pt), ans(l, m, 2*p+1, pt));
else return min(T[p].f(pt), ans(m+1, r, 2*p+2, pt));
}
long long take_photos(signed n, signed m, signed k, std::vector<signed> rw, std::vector<signed> cl) {
vector<array<int,3>> rgs(n);
for (int i=0; i<n; i++){
int l = min(rw[i], cl[i]) + 1; int r = max(rw[i], cl[i]) + 1;
rgs[i] = {l, r, 0};
}
sort(rgs.begin(), rgs.end());
int lastr = -1; vector<array<int,3>> nrgs = {{0,0,0}};
for (int i=0; i<n; i++){
int l = rgs[i][0]; int r = rgs[i][1];
if (r <= lastr) continue;
int area = (r-l+1)*(r-l+1);
if (l <= lastr) area -= (lastr-l+1)*(lastr-l+1);
lastr = r;
nrgs.push_back({l, r, area});
}
rgs = nrgs;
int totarea = 0;
for (int i=rgs.size()-1; i>=0; i--){
int area = rgs[i][1] - rgs[i][0] + 1; area *= area;
sm[i] = totarea + area;
totarea += rgs[i][2];
}
for (int i=0; i<N; i++) for (int j=0; j<2; j++) dp[i][j] = INF;
dp[0][0] = 0; dp[0][1] = 0;
line ini; ini.a = 0; ini.b = INF; for (int i=0; i<4*M; i++) T[i] = ini;
line v;
while (k--) {
for (int i=1; i<rgs.size(); i++){
// add new ln
v.b = 0; v.a = 0;
v.b += dp[i-1][0];
v.b += (rgs[i][0] - 1) * (rgs[i][0] - 1);
v.b -= sm[i];
v.a += 2 * (1 - rgs[i][0]);
add(0, M-1, 1, v);
//update ans
int area = rgs[i][1] - rgs[i][0] + 1; area *= area;
_min(dp[i][1], ans(0, M-1, 1, rgs[i][1]) + rgs[i][1] * rgs[i][1] + sm[i] - area);
_min(dp[i][1], dp[i][0]);
}
for (int i=0; i<N; i++) dp[i][0] = dp[i][1];
for (int i=0; i<N; i++) dp[i][1] = INF;
}
return sm[1] + dp[rgs.size()-1][0];
}
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define _min(x,y) x = min(x,y)
const int INF = 1e18;
const int N = 1e5+4;
int dp[N][2];
int sm[N];
struct line {
int a=0,b=0;
int f(int x) {
return a*x + b;
}
};
const int M = 1e6+4;
line T[4*M];
void add(int l, int r, int p, line &nw) {
int m = (l+r)/2;
int c1 = nw.f(m) <= T[p].f(m); int c2 = nw.f(l) <= T[p].f(l);
if (c1) swap(T[p], nw);
if (l == r) return;
if (c1^c2) add(l, m, 2*p+1, nw); else add(m+1, r, 2*p+2, nw);
}
int ans(int l, int r, int p, int pt) {
int m = (l+r)/2;
if (l == r) return T[p].f(pt);
if (pt <= m) return min(T[p].f(pt), ans(l, m, 2*p+1, pt));
else return min(T[p].f(pt), ans(m+1, r, 2*p+2, pt));
}
long long take_photos(signed n, signed m, signed k, std::vector<signed> rw, std::vector<signed> cl) {
vector<array<int,3>> rgs(n);
for (int i=0; i<n; i++){
int l = min(rw[i], cl[i]) + 1; int r = max(rw[i], cl[i]) + 1;
rgs[i] = {l, r, 0};
}
sort(rgs.begin(), rgs.end());
int lastr = -1; vector<array<int,3>> nrgs = {{0,0,0}};
for (int i=0; i<n; i++){
int l = rgs[i][0]; int r = rgs[i][1];
if (r <= lastr) continue;
int area = (r-l+1)*(r-l+1);
if (l <= lastr) area -= (lastr-l+1)*(lastr-l+1);
lastr = r;
nrgs.push_back({l, r, area});
}
rgs = nrgs;
int totarea = 0;
for (int i=rgs.size()-1; i>=0; i--){
int area = rgs[i][1] - rgs[i][0] + 1; area *= area;
sm[i] = totarea + area;
totarea += rgs[i][2];
}
for (int i=0; i<N; i++) for (int j=0; j<2; j++) dp[i][j] = INF;
dp[0][0] = 0; dp[0][1] = 0;
line ini; ini.a = 0; ini.b = INF; for (int i=0; i<4*M; i++) T[i] = ini;
line v;
while (k--) {
for (int i=1; i<rgs.size(); i++){
// add new ln
v.b = 0; v.a = 0;
v.b += dp[i-1][0];
v.b += (rgs[i][0] - 1) * (rgs[i][0] - 1);
v.b -= sm[i];
v.a += 2 * (1 - rgs[i][0]);
add(0, M-1, 1, v);
//update ans
int area = rgs[i][1] - rgs[i][0] + 1; area *= area;
_min(dp[i][1], ans(0, M-1, 1, rgs[i][1]) + rgs[i][1] * rgs[i][1] + sm[i] - area);
_min(dp[i][1], dp[i][0]);
}
for (int i=0; i<N; i++) dp[i][0] = dp[i][1];
for (int i=0; i<N; i++) dp[i][1] = INF;
}
return sm[1] + dp[rgs.size()-1][0];
}