Submission #921863

# Submission time Handle Problem Language Result Execution time Memory
921863 2024-02-04T12:17:02 Z josanneo22 Salesman (IOI09_salesman) C++17
60 / 100
779 ms 57540 KB
#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) };
		}
	};
	vector<node> tr;
	segtree(int n){ tr.resize(n << 2);}
	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] = -1E18; 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(M), back(M);
	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[ord[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

salesman.cpp:1: warning: ignoring '#pragma warning ' [-Wunknown-pragmas]
    1 | #pragma warning(suppress : 4996)
      |
# Verdict Execution time Memory Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 348 KB Output is correct
4 Correct 2 ms 604 KB Output is correct
5 Correct 4 ms 860 KB Output is correct
6 Correct 16 ms 2776 KB Output is correct
7 Correct 46 ms 6104 KB Output is correct
8 Correct 99 ms 11728 KB Output is correct
9 Correct 152 ms 17616 KB Output is correct
10 Correct 370 ms 35564 KB Output is correct
11 Correct 411 ms 34532 KB Output is correct
12 Correct 548 ms 46800 KB Output is correct
13 Correct 566 ms 45892 KB Output is correct
14 Correct 667 ms 57180 KB Output is correct
15 Correct 689 ms 57540 KB Output is correct
16 Correct 743 ms 57540 KB Output is correct
17 Incorrect 0 ms 348 KB Output isn't correct
18 Incorrect 0 ms 348 KB Output isn't correct
19 Incorrect 1 ms 388 KB Output isn't correct
20 Incorrect 2 ms 604 KB Output isn't correct
21 Incorrect 2 ms 604 KB Output isn't correct
22 Incorrect 4 ms 860 KB Output isn't correct
23 Incorrect 4 ms 860 KB Output isn't correct
24 Incorrect 4 ms 1116 KB Output isn't correct
25 Incorrect 97 ms 11956 KB Output isn't correct
26 Incorrect 195 ms 23240 KB Output isn't correct
27 Incorrect 445 ms 40284 KB Output isn't correct
28 Incorrect 452 ms 40860 KB Output isn't correct
29 Incorrect 779 ms 57348 KB Output isn't correct
30 Incorrect 715 ms 57540 KB Output isn't correct