# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
928550 | boris_mihov | Salesman (IOI09_salesman) | C++17 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <queue>
#include <set>
typedef long long llong;
const int MAXN = 500000 + 10;
const llong INF = 4e18;
int n;
llong d, u;
struct Event
{
int pos;
int time;
llong cost;
friend bool operator < (const Event &a, const Event &b)
{
return a.time < b.time;
}
};
struct SegmentTree
{
llong tree[4*MAXN];
void build(int l, int r, int node)
{
if (l == r)
{
tree[node] = -INF;
return;
}
int mid = (l + r) / 2;
build(l, mid, 2*node);
build(mid + 1, r, 2*node + 1);
tree[node] = std::max(tree[2*node], tree[2*node + 1]);
}
void update(int l, int r, int node, int queryPos, int queryVal)
{
if (l == r)
{
tree[node] = std::max(tree[node], queryVal);
return;
}
int mid = (l + r) / 2;
if (queryPos <= mid) update(l, mid, 2*node, queryPos, queryVal);
else update(mid + 1, r, 2*node + 1, queryPos, queryVal);
tree[node] = std::max(tree[2*node], tree[2*node + 1]);
}
llong query(int l, int r, int node, int queryL, int queryR)
{
if (queryL <= l && r <= queryR)
{
return tree[node];
}
int res = -INF;
int mid = (l + r) / 2;
if (queryL <= mid) res = query(l, mid, 2*node, queryL, queryR);
if (mid + 1 <= queryR) res = std::max(res, query(mid + 1, r, 2*node + 1, queryL, queryR));
return res;
}
void build()
{
build(1, MAXN - 1, 1);
}
void update(int pos, int val)
{
update(1, MAXN - 1, 1, pos, val);
}
int query(int l, int r)
{
return query(1, MAXN - 1, 1, l, r);
}
};
SegmentTree treeU;
SegmentTree treeD;
Event event[MAXN];
llong dp[MAXN];
void solve()
{
treeU.build();
treeD.build();
std::sort(event + 1, event + 1 + n);
for (int i = n ; i >= 0 ; --i)
{
if (event[i].pos <= event[0].pos) dp[i] = -(event[0].pos - event[i].pos) * d;
else dp[i] = -(event[i].pos - event[0].pos) * u;
dp[i] = std::max(dp[i], treeU.query(1, event[i].pos) - event[i].pos * u);
dp[i] = std::max(dp[i], treeD.query(event[i].pos, MAXN - 1) + event[i].pos * d);
treeU.update(event[i].pos, dp[i] + event[i].cost + event[i].pos * u);
treeD.update(event[i].pos, dp[i] + event[i].cost - event[i].pos * d);
}
std::cout << dp[0] << '\n';
}
void input()
{
std::cin >> n >> u >> d >> event[0].pos;
for (int i = 1 ; i <= n ; ++i)
{
std::cin >> event[i].time >> event[i].pos >> event[i].cost;
}
}
void fastIOI()
{
std::ios_base :: sync_with_stdio(0);
std::cout.tie(nullptr);
std::cin.tie(nullptr);
}
int main()
{
fastIOI();
input();
solve();
return 0;
}