# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
973216 | wapas | Salesman (IOI09_salesman) | C++17 | 393 ms | 33228 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
// code by wapas
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
segtree code by : https://github.com/atcoder/ac-library/blob/master/atcoder/segtree.hpp
how to use : https://github.com/atcoder/ac-library/blob/master/document_en/segtree.md
*/
#if __cplusplus < 202002L
unsigned int bit_ceil(unsigned int n) {
unsigned int x = 1;
while (x < (unsigned int)(n)) x *= 2;
return x;
}
#endif
int countr_zero(unsigned int n) {
#ifdef _MSC_VER
unsigned long index;
_BitScanForward(&index, n);
return index;
#else
return __builtin_ctz(n);
#endif
}
template <class S, auto op, auto e> struct segtree {
static_assert(is_convertible_v<decltype(op), function<S(S, S)>>,
"op must work as S(S, S)");
static_assert(is_convertible_v<decltype(e), function<S()>>,
"e must work as S()");
public:
segtree() : segtree(0) {}
explicit segtree(int n) : segtree(vector<S>(n, e())) {}
explicit segtree(const vector<S>& v) : _n(int(v.size())) {
size = (int) bit_ceil((unsigned int)(_n));
log = countr_zero((unsigned int)size);
d = vector<S>(2 * size, e());
for (int i = 0; i < _n; i++) d[size + i] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, S x) {
assert(0 <= p && p < _n);
p += size;
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) const {
assert(0 <= p && p < _n);
return d[p + size];
}
S prod(int l, int r) const {
assert(0 <= l && l <= r && r <= _n);
S sml = e(), smr = e();
l += size;
r += size;
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() const { return d[1]; }
template <bool (*f)(S)> int max_right(int l) const {
return max_right(l, [](S x) { return f(x); });
}
template <class F> int max_right(int l, F f) const {
assert(0 <= l && l <= _n);
assert(f(e()));
if (l == _n) return _n;
l += size;
S sm = e();
do {
while (l % 2 == 0) l >>= 1;
if (!f(op(sm, d[l]))) {
while (l < size) {
l = (2 * l);
if (f(op(sm, d[l]))) {
sm = op(sm, d[l]);
l++;
}
}
return l - size;
}
sm = op(sm, d[l]);
l++;
} while ((l & -l) != l);
return _n;
}
template <bool (*f)(S)> int min_left(int r) const {
return min_left(r, [](S x) { return f(x); });
}
template <class F> int min_left(int r, F f) const {
assert(0 <= r && r <= _n);
assert(f(e()));
if (r == 0) return 0;
r += size;
S sm = e();
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!f(op(d[r], sm))) {
while (r < size) {
r = (2 * r + 1);
if (f(op(d[r], sm))) {
sm = op(d[r], sm);
r--;
}
}
return r + 1 - size;
}
sm = op(d[r], sm);
} while ((r & -r) != r);
return 0;
}
private:
int _n, size, log;
vector<S> d;
void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
struct market {
ll date, pos, profit;
bool operator < (const market &o) const {
if (date == o.date) return pos < o.pos;
return date < o.date;
}
};
ll op(ll a, ll b) {
return max(a, b);
}
const ll inf = -1e18;
ll e() {
return inf;
}
#define SEG_MAX 505050
void solution(int t) {
int N, U, D, S; cin >> N >> U >> D >> S;
vector<market> arr;
arr.push_back({ (int) 1e8, -1, 0 });
for (int i = 0; i < N; i++) {
ll d, p, c; cin >> d >> p >> c;
arr.push_back({ d, p, c });
}
N += 1;
sort(arr.begin(), arr.end());
segtree<ll, op, e> stD(SEG_MAX), stU(SEG_MAX);
auto setST = [&](int x, int v) {
stD.set(x, v + x * D);
stU.set(x, v - x * U);
};
auto getST = [&](int x) {
return max(stD.prod(0, x) - x * D, stU.prod(x + 1, SEG_MAX) + x * U);
};
setST(S, 0);
ll last = arr[0].date, lastIdx = 0;
for (int i = 0; i < N; i++) {
if (last == arr[i].date) continue;
int M = i - lastIdx;
vector<ll> cacheD(M, inf), cacheU(M, inf);
for (int j = 0; j < M; j++) {
int k = lastIdx + j;
cacheD[j] = cacheU[j] = getST(arr[k].pos);
}
for (int j = 0; j < M; j++) {
int k = lastIdx + j;
if (j != 0) cacheD[j] = max(cacheD[j], cacheD[j - 1] - (arr[k].pos - arr[k - 1].pos) * D);
cacheD[j] += arr[k].profit;
}
for (int j = M - 1; j >= 0; j--) {
int k = lastIdx + j;
if (j != M - 1) cacheU[j] = max(cacheU[j], cacheU[j + 1] - (arr[k + 1].pos - arr[k].pos) * U);
cacheU[j] += arr[k].profit;
}
for (int j = 0; j < M; j++) {
int k = lastIdx + j;
setST(arr[k].pos, max(cacheD[j], cacheU[j]));
}
last = arr[i].date; lastIdx = i;
}
cout << getST(S);
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
// int T; cin >> T;
int T = 1;
for (int t = 0; t < T; t++) {
solution(t);
}
}
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |