Submission #921862

#TimeUsernameProblemLanguageResultExecution timeMemory
921862josanneo22Salesman (IOI09_salesman)C++17
0 / 100
282 ms62540 KiB
#pragma warning(suppress : 4996) #include <bits/stdc++.h> using namespace std; using i64 = long long; #define L(i,j,k) for(int i=(j);i<=(k);++i) #define R(i,j,k) for(int i=(j);i>=(k);--i) #define all(x) x.begin(),x.end() #define me(x,a) memset(x,a,sizeof(x)) struct segtree { struct node { i64 mx; friend node operator + (const node& A, const node& B) { return { max(A.mx, B.mx) }; } }; node tr[10000 * 4]; void build(int p, int l, int r) { if (l == r) { tr[p].mx = -1E18; return; } int mid = (l + r) >> 1; build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r); tr[p] = tr[p << 1] + tr[p << 1 | 1]; } void update(int p, int l, int r, int x, i64 v) { if (l == x && l == r) { tr[p].mx = max(tr[p].mx, v); return; } int mid = (l + r) >> 1; if (x <= mid) update(p << 1, l, mid, x, v); if (x >= mid + 1) update(p << 1 | 1, mid + 1, r, x, v); tr[p] = tr[p << 1] + tr[p << 1 | 1]; } node query(int p, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) return tr[p]; if (l > qr || r < ql) return { (i64) - 1E18}; int mid = (l + r) >> 1; if (ql <= mid && qr >= mid + 1) return query(p << 1, l, mid, ql, qr) + query(p << 1 | 1, mid + 1, r, ql, qr); if (ql <= mid) return query(p << 1, l, mid, ql, qr); if (qr >= mid + 1) return query(p << 1 | 1, mid + 1, r, ql, qr); return { (i64)-1E18 }; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int N; i64 U, D, S; cin >> N >> U >> D >> S; //dp[i] = max profit after considering all events until i //dp[i] = dp[j] + (pos[i] - pos[j]) * U if pos[i] <= pos[j] //dp[i] = dp[j] + (pos[j] - pos[i]) * D if pos[i] > pos[j] /* if (pos[ord[i]] <= pos[ord[j]]) dp[i] = max(dp[i], dp[j] + profit[ord[i]] - (pos[ord[j]] - pos[ord[i]]) * D); dp[i] = (max(dp[j] - pos[ord[j]] * D)) + (profit[ord[i]] + pos[ord[i]] * D); for each j that has pos[ord[j]] > pos[ord[i]] if we are using a segtree, we are querying on [o(pos[ord[i]), +inf) o(x) is the relative position then we try to set o(pos[ord[i]]) to be dp[i] (set max) */ vector<i64> dp(N + 2, -1E18); vector<i64> date(N + 2), pos(N + 2), profit(N + 2); L(i, 1, N) cin >> date[i] >> pos[i] >> profit[i]; pos[0] = S; date[0] = 0; pos[N + 1] = S; date[N + 1] = 1E18; vector<int> ord(N + 2); iota(all(ord), 0); sort(ord.begin(), ord.end(), [&](int i, int j) { return date[i] < date[j]; }); vector<i64> relative_pos, actual_pos(N + 2); L(i, 0, N + 1) relative_pos.push_back(pos[i]); sort(all(relative_pos)); relative_pos.resize(unique(all(relative_pos)) - relative_pos.begin()); int M = relative_pos.size(); L(i, 0, N + 1) { actual_pos[i] = pos[i]; pos[i] = lower_bound(all(relative_pos), pos[i]) - relative_pos.begin() + 1; } dp[0] = 0; segtree front, back; front.build(1, 1, M); back.build(1, 1, M); front.update(1, 1, M, pos[0], actual_pos[0] * D); back.update(1, 1, M, pos[0], -actual_pos[0] * U); L(i, 1, N + 1) { i64 val_front = front.query(1, 1, M, 1, pos[ord[i]]).mx; i64 val_back = back.query(1, 1, M, pos[ord[i]], M).mx; val_front = val_front - actual_pos[ord[i]] * D; val_back = val_back + actual_pos[ord[i]] * U; dp[i] = max(val_front, val_back) + profit[i]; front.update(1, 1, M, pos[ord[i]], dp[i] + actual_pos[ord[i]] * D); back.update(1, 1, M, pos[ord[i]], dp[i] - actual_pos[ord[i]] * U); } cout << dp[N + 1] << '\n'; }

Compilation message (stderr)

salesman.cpp:1: warning: ignoring '#pragma warning ' [-Wunknown-pragmas]
    1 | #pragma warning(suppress : 4996)
      |
#Verdict Execution timeMemoryGrader output
Fetching results...