Submission #921865

# Submission time Handle Problem Language Result Execution time Memory
921865 2024-02-04T12:30:20 Z josanneo22 Salesman (IOI09_salesman) C++17
62 / 100
821 ms 57436 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 604 KB Output is correct
5 Correct 5 ms 860 KB Output is correct
6 Correct 16 ms 2776 KB Output is correct
7 Correct 46 ms 6192 KB Output is correct
8 Correct 125 ms 11952 KB Output is correct
9 Correct 150 ms 17608 KB Output is correct
10 Correct 356 ms 35776 KB Output is correct
11 Correct 372 ms 34952 KB Output is correct
12 Correct 525 ms 46008 KB Output is correct
13 Correct 549 ms 45784 KB Output is correct
14 Correct 772 ms 57348 KB Output is correct
15 Correct 642 ms 57344 KB Output is correct
16 Correct 821 ms 57436 KB Output is correct
17 Correct 0 ms 344 KB Output is correct
18 Incorrect 0 ms 348 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 620 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 860 KB Output isn't correct
25 Incorrect 86 ms 11952 KB Output isn't correct
26 Incorrect 192 ms 23296 KB Output isn't correct
27 Incorrect 458 ms 41152 KB Output isn't correct
28 Incorrect 477 ms 40128 KB Output isn't correct
29 Incorrect 680 ms 57368 KB Output isn't correct
30 Incorrect 622 ms 57356 KB Output isn't correct