社区讨论
已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 条回复,欢迎继续交流。
正在加载回复...