1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
struct Line {
long long m, b; // y = m*x + b
long long get(long long x) const { return m * x + b; }
};
struct Node {
Line ln;
Node *l, *r;
Node(const Line& line) : ln(line), l(nullptr), r(nullptr) {}
};
struct LiChao {
long long X_MIN, X_MAX;
Node* root;
LiChao(long long xmin, long long xmax) : X_MIN(xmin), X_MAX(xmax), root(nullptr) {}
void add_line(Line nw) { insert(root, X_MIN, X_MAX, nw); }
void insert(Node*& node, long long l, long long r, Line nw) {
if (!node) { node = new Node(nw); return; }
long long mid = (l + r) >> 1;
bool leftBetter = nw.get(l) < node->ln.get(l);
bool midBetter = nw.get(mid) < node->ln.get(mid);
if (midBetter) swap(nw, node->ln);
if (l == r) return;
if (leftBetter != midBetter) insert(node->l, l, mid, nw);
else insert(node->r, mid + 1, r, nw);
}
long long query(long long x) const { return query(root, X_MIN, X_MAX, x); }
long long query(Node* node, long long l, long long r, long long x) const {
if (!node) return LLONG_MAX / 4;
long long res = node->ln.get(x);
if (l == r) return res;
long long mid = (l + r) >> 1;
if (x <= mid) return min(res, query(node->l, l, mid, x));
return min(res, query(node->r, mid + 1, r, x));
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
if (!(cin >> n)) return 0;
vector<int> d(n - 1);
long long totalDist = 0;
for (int i = 0; i < n - 1; ++i) {
cin >> d[i];
totalDist += d[i];
}
// prefix distance D[i]: distance from planet 1 to planet i
vector<long long> D(n + 1, 0); // 1-indexed, D[1]=0
for (int i = 2; i <= n; ++i) D[i] = D[i - 1] + d[i - 2];
vector<long long> p(n + 1, 0), s(n + 1, 0); // only 1..n-1 used
for (int i = 1; i <= n - 1; ++i) cin >> p[i] >> s[i];
vector<long long> dp(n + 1, 0);
LiChao lichao(0, totalDist);
// Start: can board at planet 1
lichao.add_line({s[1], dp[1] + p[1] - s[1] * D[1]});
for (int j = 2; j <= n; ++j) {
dp[j] = lichao.query(D[j]);
if (j <= n - 1) {
long long b = dp[j] + p[j] - s[j] * D[j];
lichao.add_line({s[j], b});
}
}
cout << dp[n] << '\n';
return 0;
}
|