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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
struct FenwickMax {
int n;
vector<long long> bit;
static constexpr long long NEG_INF = -(1LL<<60);
FenwickMax() {}
FenwickMax(int n): n(n), bit(n+1, NEG_INF) {}
void init(int n_) { n = n_; bit.assign(n+1, NEG_INF); }
void update(int idx, long long val) {
for (int i = idx; i <= n; i += i & -i) bit[i] = max(bit[i], val);
}
long long query(int idx) const {
long long res = NEG_INF;
for (int i = idx; i > 0; i -= i & -i) res = max(res, bit[i]);
return res;
}
};
struct Item {
int day;
int idx;
int pos;
int profit;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, U, D, S;
if (!(cin >> N >> U >> D >> S)) return 0;
vector<Item> items; items.reserve(N);
vector<int> coords; coords.reserve(N + 1); coords.push_back(S);
for (int i = 0; i < N; ++i) {
int T, L, M; cin >> T >> L >> M;
items.push_back({T, 0, L, M});
coords.push_back(L);
}
sort(coords.begin(), coords.end());
coords.erase(unique(coords.begin(), coords.end()), coords.end());
int P = (int)coords.size();
auto get_idx = [&](int x){ return int(lower_bound(coords.begin(), coords.end(), x) - coords.begin()) + 1; };
for (auto &it : items) it.idx = get_idx(it.pos);
int S_idx = get_idx(S);
sort(items.begin(), items.end(), [](const Item& a, const Item& b){
if (a.day != b.day) return a.day < b.day;
return a.idx < b.idx;
});
const long long NEG_INF = -(1LL<<60);
vector<long long> base(P+1, NEG_INF);
base[S_idx] = 0;
FenwickMax fenwLeft(P), fenwRight(P);
fenwLeft.update(S_idx, base[S_idx] + 1LL*D*coords[S_idx-1]);
fenwRight.update(P - S_idx + 1, base[S_idx] - 1LL*U*coords[S_idx-1]);
int i = 0;
while (i < N) {
int j = i, curDay = items[i].day;
while (j < N && items[j].day == curDay) ++j;
int m = j - i;
vector<int> idxs(m+1), pos(m+1), profit(m+1);
for (int k = 1; k <= m; ++k) {
idxs[k] = items[i + k - 1].idx;
pos[k] = items[i + k - 1].pos;
profit[k] = items[i + k - 1].profit;
}
vector<long long> H(m+1, NEG_INF);
for (int k = 1; k <= m; ++k) {
int idx = idxs[k];
long long leftBest = fenwLeft.query(idx);
long long rightBest = fenwRight.query(P - idx);
long long cand = NEG_INF;
if (leftBest != NEG_INF) cand = max(cand, leftBest - 1LL*D*pos[k]);
if (rightBest != NEG_INF) cand = max(cand, rightBest + 1LL*U*pos[k]);
H[k] = cand;
}
vector<long long> pref(m+1, 0);
for (int k = 1; k <= m; ++k) pref[k] = pref[k-1] + profit[k];
vector<long long> V1(m+1, NEG_INF);
long long prefBest = NEG_INF;
for (int b = 1; b <= m; ++b) {
long long T1 = H[b] - pref[b-1] + 1LL*D*pos[b];
prefBest = max(prefBest, T1);
V1[b] = pref[b] - 1LL*D*pos[b] + prefBest;
}
vector<long long> V2(m+1, NEG_INF);
long long suffBest = NEG_INF;
for (int a = m; a >= 1; --a) {
long long T2 = H[a] - 1LL*U*pos[a] + pref[a];
suffBest = max(suffBest, T2);
V2[a] = 1LL*U*pos[a] - pref[a-1] + suffBest;
}
for (int k = 1; k <= m; ++k) {
int idx = idxs[k];
long long newBase = max(V1[k], V2[k]);
if (newBase > base[idx]) {
base[idx] = newBase;
fenwLeft.update(idx, base[idx] + 1LL*D*pos[k]);
fenwRight.update(P - idx + 1, base[idx] - 1LL*U*pos[k]);
}
}
i = j;
}
long long ans = 0;
for (int p = 1; p <= P; ++p) {
if (base[p] == NEG_INF) continue;
long long cost = (coords[p-1] <= S) ? 1LL*D*(S - coords[p-1]) : 1LL*U*(coords[p-1] - S);
ans = max(ans, base[p] - cost);
}
cout << ans << '\n';
return 0;
}
|