社区讨论

求助!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;
}
用的倍增法
st[i][j][0/1]st[i][j][0/1] 表示 i城市,2j天,A(0)B(1)开始开车的答案第i城市,2^j天,A(0)或B(1)开始开车的答案

回复

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

正在加载回复...