社区讨论
求助!WA on 16,不明错误
P1081[NOIP 2012 提高组] 开车旅行参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhz43y5q
- 此快照首次捕获于
- 2025/11/15 01:08 4 个月前
- 此快照最后确认于
- 2025/11/16 13:41 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 5e5 + 5, MAXLG = 20;
ll n, m, s[MAXN], x[MAXN], x0;
struct Ans{ll da, db, to;}st[MAXN][MAXLG][2];
int cur[MAXN];
struct City{ll h, num;}c[MAXN];
bool cmp(City a, City b){return a.h < b.h;}
struct Node{City ci; ll pre, nxt;}li[MAXN];
Ans add(Ans a, Ans b){Ans res;res.da = a.da + b.da;res.db = a.db + b.db;res.to = b.to;return res;}
signed main(){
cin.tie(0) -> sync_with_stdio(false);
cin >> n;
for(int i = 1; i <= n; i++){cin >> c[i].h; c[i].num = i;}
cin >> x0 >> m;
for(int i = 1; i <= m; i++)cin >> s[i] >> x[i];
sort(c + 1, c + n + 1, cmp);
for(int i = 1; i <= n; i++){
li[i].ci = c[i];
li[i].pre = i - 1; li[i].nxt = i + 1;
cur[c[i].num] = i;
}
for(int i = 1; i <= n; i++){
ll pre = li[cur[i]].pre, nxt = li[cur[i]].nxt, dp = abs(li[pre].ci.h - li[cur[i]].ci.h), dn = abs(li[nxt].ci.h - li[cur[i]].ci.h);
ll ppre = li[pre].pre, nnxt = li[nxt].nxt, dpp = abs(li[ppre].ci.h - li[cur[i]].ci.h), dnn = abs(li[nnxt].ci.h - li[cur[i]].ci.h);
dpp = abs(li[ppre].ci.h - li[cur[i]].ci.h), dnn = abs(li[nnxt].ci.h - li[cur[i]].ci.h);
dp = abs(li[pre].ci.h - li[cur[i]].ci.h), dn = abs(li[nxt].ci.h - li[cur[i]].ci.h);
if(ppre != 0){
if(pre == 0){dp = dpp; pre = ppre;}
else if(nxt == n + 1 || nxt == 0){dn = dpp; nxt = ppre;}
else if(dp > dn && dpp < max(dp, dn) && ppre != nxt){dp = dpp;pre = ppre;}
else if(dn > dp && dpp < max(dp, dn) && ppre != pre){dn = dpp; nxt = ppre;}
}
if(nnxt != n + 1 && nnxt != 0){
if(pre == 0){dp = dnn; pre = nnxt;}
else if(nxt == n + 1 || nxt == 0){dn = dnn; nxt = nnxt;}
else if(dp > dn && dnn < max(dp, dn) && nnxt != nxt){dp = dnn;pre = nnxt;}
else if(dn > dp && dnn < max(dp, dn) && nnxt != pre){dn = dnn; nxt = nnxt;}
}
dp = abs(li[pre].ci.h - li[cur[i]].ci.h), dn = abs(li[nxt].ci.h - li[cur[i]].ci.h);
if(pre > nxt){swap(pre, nxt), swap(dp, dn);}
if(pre == 0 && (nxt == n + 1 || nxt == 0));
else if(pre == 0 && nxt != n + 1 && nxt != 0){
st[i][0][0] = {0, 0, 0};
st[i][0][1] = {0, dn, li[nxt].ci.num};
}
else if(nxt == n + 1 && pre != 0){
st[i][0][0] = {0, 0, 0};
st[i][0][1] = {0, dp, li[pre].ci.num};
}
else{
if(abs(li[pre].ci.h - li[cur[i]].ci.h) > abs(li[nxt].ci.h - li[cur[i]].ci.h)){
st[i][0][0] = {dp, 0, li[pre].ci.num};
st[i][0][1] = {0, dn, li[nxt].ci.num};
}
else if(abs(li[pre].ci.h - li[cur[i]].ci.h) == abs(li[nxt].ci.h - li[cur[i]].ci.h)){
if(li[pre].ci.h < li[nxt].ci.h){
st[i][0][0] = {dn, 0, li[nxt].ci.num};
st[i][0][1] = {0, dp, li[pre].ci.num};
}
else{
st[i][0][0] = {dp, 0, li[pre].ci.num};
st[i][0][1] = {0, dn, li[nxt].ci.num};
}
}
else{
st[i][0][0] = {dn, 0, li[nxt].ci.num};
st[i][0][1] = {0, dp, li[pre].ci.num};
}
}
pre = li[cur[i]].pre, nxt = li[cur[i]].nxt;
li[pre].nxt = li[cur[i]].nxt;
li[nxt].pre = li[cur[i]].pre;
}
for(int j = 1; j <= n; j++){
if(st[j][0][0].to != 0)st[j][1][0] = add(st[j][0][0], st[st[j][0][0].to][0][1]);
if(st[j][0][1].to != 0)st[j][1][1] = add(st[j][0][1], st[st[j][0][1].to][0][0]);
}
for(int i = 2; i < MAXLG; i++)
for(int j = 1; j <= n; j++){
if(st[j][i - 1][0].to != 0)st[j][i][0] = add(st[j][i - 1][0], st[st[j][i - 1][0].to][i - 1][0]);
if(st[j][i - 1][1].to != 0)st[j][i][1] = add(st[j][i - 1][1], st[st[j][i - 1][1].to][i - 1][1]);
}
ll ans1 = -1;double val = (ll)(0x3f3f3f3f3f3f3f3f);
for(int i = 1; i <= n; i++){
ll cur = i, sum = 0, sua = 0, sub = 0;
for(int j = MAXLG - 1; j >= 0; j--){
ll da = st[cur][j][0].da, db = st[cur][j][0].db;
if(st[cur][j][0].to != 0 && sum + da + db <= x0){
cur = st[cur][j][0].to;
sum += da + db;
sua += da; sub += db;
}
}
if(ans1 == -1 || val > (sub == 0 ? (ll)(0x3f3f3f3f3f3f3f3f) : (double)sua / sub)){
ans1 = i;
val = (sub == 0 ? (ll)(0x3f3f3f3f3f3f3f3f) : (double)sua / sub);
}
}
cout << ans1 << endl;
for(int i = 1; i <= m; i++){
ll cur = s[i], sum = 0, sua = 0, sub = 0;
for(int j = MAXLG - 1; j >= 0; j--){
ll da = st[cur][j][0].da, db = st[cur][j][0].db;
if(st[cur][j][0].to != 0 && sum + da + db <= x[i]){
cur = st[cur][j][0].to;
sum += da + db;
sua += da; sub += db;
}
}
cout << sua << ' ' << sub << endl;
}
return 0;
}
用的倍增法
表示
回复
共 0 条回复,欢迎继续交流。
正在加载回复...