社区讨论

已AC,但做法有些奇怪,不知道对不对,求纠错或证明

P2672[NOIP 2015 普及组] 推销员参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lo7u4n7o
此快照首次捕获于
2023/10/27 07:48
2 年前
此快照最后确认于
2023/10/27 07:48
2 年前
查看原帖
要求疲劳值最多,可以考虑对于选i个而言,其答案一定是在选了i-1个使得答案最大的基础上再选一个,若前i-1个的最大疲劳值为V,距离为S,则V,S可由所有距离<=S的未被选过的点,以及所有距离>S的点更新
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mid ((l + r) >> 1)
#define INF -1000000000000000ll
#define In inline
#define lch (R << 1)
#define rch ((R << 1) | 1)
struct Point {
	ll val, S;
}d[100005];
struct Node {
	ll Max, W, Max2, W2;
} tree[400005];
bool cmp(Point a, Point b) {
	return a.S < b.S || (a.S == b.S && a.val > b.val);
}
ll N, S, V;
In void Pushup(Node &R2, Node &lch2, Node &rch2) {
	R2.Max = max(lch2.Max, rch2.Max);
	R2.Max2 = max(lch2.Max2, rch2.Max2);
	lch2.Max2 >= rch2.Max2 ? R2.W2 = lch2.W2 : R2.W2 = rch2.W2;
	lch2.Max >= rch2.Max ? R2.W = lch2.W : R2.W = rch2.W;
}
void Update(ll R, ll l, ll r, ll k, ll v) {
	if(l == r) {
		tree[R].Max = v;
		tree[R].Max2 = 2 * d[l].S + v;
		return;
	}
	if(k <= mid) Update(lch, l, mid, k, v);
	else Update(rch, mid + 1, r, k, v);
	Pushup(tree[R], tree[lch], tree[rch]);
}
Node Query(ll R, ll l, ll r, ll ql, ll qr) {
	if(ql > qr) return (Node){INF, INF, INF, INF};
	if(l >= ql && r <= qr) return tree[R];
	Node Ans, C1, C2;
	C1.W = C2.W = INF;
	C1.Max = C2.Max = INF;
	C1.W2 = C2.W2 = C1.Max2 = C2.Max2 = INF;
	if(mid >= ql) C1 = Query(lch, l, mid, ql, qr);
	if(mid + 1 <= qr) C2 = Query(rch, mid + 1, r, ql, qr);
	Pushup(Ans, C1, C2);
	return Ans;
}
void Build(ll R, ll l, ll r) {
	if(l == r) {tree[R].Max = d[l].val; tree[R].W = l; tree[R].W2 = l; tree[R].Max2 = d[l].S * 2 + d[l].val;return;}
	Build(lch, l, mid);
	Build(rch, mid + 1, r);
	Pushup(tree[R], tree[lch], tree[rch]);
}
ll Judge() {
	ll l = 1, r = N + 1, Ans = -1e15;
	while(l <= r) {
		if(d[mid].S <= S) {
			Ans = mid;
			l = mid + 1;
		}
		else r = mid - 1;
	}
	return Ans;
}
int main()
{
	cin >> N;
	for(int i = 1; i <= N; i++) cin >> d[i].S;
	for(int i = 1; i <= N; i++) cin >> d[i].val;
	sort(d + 1, d + N + 1, cmp);
	Build(1, 1, N);
	for(int i = 1; i <= N; i++) {
		ll Wh = Judge();
		Node L = Query(1, 1, N, 1, Wh), R = Query(1, 1, N, Wh + 1, N);
		if(V + L.Max >= V - 2 * S + R.Max2) {
			V = V + L.Max;
//			cout << L.W << "WAWAWA "; 
			Update(1, 1, N, L.W, INF);
		}
		else {
			V = V - 2 * S + R.Max2;
			S = d[R.W2].S;
//			cout << R.W2 << "WAWAWA ";
			Update(1, 1, N, R.W2, INF);
		}
		cout << V << "\n";
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...