Submission #921866

# Submission time Handle Problem Language Result Execution time Memory
921866 2024-02-04T12:31:13 Z josanneo22 Salesman (IOI09_salesman) C++17
62 / 100
827 ms 57448 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 == 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) { 
		if(date[i] != date[j]) return date[i] < date[j]; 
		return pos[i] > pos[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 + 50), back(M + 50);
	front.build(1, 1, M); back.build(1, 1, M);
	front.update(1, 1, M, pos[0], actual_pos[0] * U);
	back.update(1, 1, M, pos[0], -actual_pos[0] * D);
	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]] * U;
		val_back = val_back + actual_pos[ord[i]] * D;
		dp[i] = max(val_front, val_back) + profit[ord[i]];
		front.update(1, 1, M, pos[ord[i]], dp[i] + actual_pos[ord[i]] * U);
		back.update(1, 1, M, pos[ord[i]], dp[i] - actual_pos[ord[i]] * D);
	}
	cout << max(0LL, 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 0 ms 348 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 600 KB Output is correct
5 Correct 4 ms 860 KB Output is correct
6 Correct 18 ms 2848 KB Output is correct
7 Correct 44 ms 6108 KB Output is correct
8 Correct 101 ms 11724 KB Output is correct
9 Correct 144 ms 17436 KB Output is correct
10 Correct 331 ms 35548 KB Output is correct
11 Correct 363 ms 35568 KB Output is correct
12 Correct 599 ms 46528 KB Output is correct
13 Correct 593 ms 46008 KB Output is correct
14 Correct 783 ms 57440 KB Output is correct
15 Correct 783 ms 57356 KB Output is correct
16 Correct 827 ms 57352 KB Output is correct
17 Correct 1 ms 348 KB Output is correct
18 Incorrect 1 ms 360 KB Output isn't correct
19 Incorrect 1 ms 348 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 1032 KB Output isn't correct
23 Incorrect 4 ms 1112 KB Output isn't correct
24 Incorrect 4 ms 1040 KB Output isn't correct
25 Incorrect 85 ms 11948 KB Output isn't correct
26 Incorrect 209 ms 23312 KB Output isn't correct
27 Incorrect 435 ms 40520 KB Output isn't correct
28 Incorrect 465 ms 40288 KB Output isn't correct
29 Incorrect 732 ms 57344 KB Output isn't correct
30 Incorrect 708 ms 57448 KB Output isn't correct