[NOIP 2012 提高组] 开车旅行 的AC代码

传送门

#include<bits/stdc++.h>
using namespace std;
#define int long long

const int N=1e5+10;

int n,h[N],f[N][18],sa[N][18],sb[N][18],A[N],B[N];
set<int>s;
map<int,int>mp;

main(void){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);	
	
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>h[i];
		mp[h[i]]=i;
	}
	s.insert(h[n]);
	for(int i=n-1;i>=1;i--){//一路向东 
		set<int>::iterator it=s.lower_bound(h[i]);
		vector<int>t;
		if(it!=s.end()){
			t.push_back(*it);
			if(next(it)!=s.end())t.push_back(*next(it));
		}
		if(it!=s.begin()){
			t.push_back(*prev(it));
			if(prev(it)!=s.begin())t.push_back(*prev(prev(it)));
		}
		sort(t.begin(),t.end());
		if(t.size()>1){
			int p=0,q=0;
			for(int j=1;j<t.size();j++){
				if(abs(h[i]-t[j])<abs(h[i]-t[p])){
					p=j;
				}
			}
			if(!p)q=1;
			for(int j=1;j<t.size();j++){
				if(abs(h[i]-t[j])<abs(h[i]-t[q]) and p!=j){
					q=j;
				}
			}
			A[i]=mp[t[q]];
			B[i]=mp[t[p]];
		}else{
			B[i]=mp[t[0]];
		}
		s.insert(h[i]);
	}
	
//	for(int i=1;i<=n;i++){
//		cout<<"i:"<<i<<"  A:"<<A[i]<<"  B:"<<B[i]<<endl;
//	} 
	
	for(int i=1;i<=n;i++){
		f[i][0]=A[i];
		f[i][1]=B[A[i]];
	}
	
	for(int j=2;j<=17;j++){
		for(int i=1;i<=n;i++){
			f[i][j]=f[f[i][j-1]][j-1];
		}
	}
	
	for(int i=1;i<=n;i++){
		sa[i][0]=sa[i][1]=abs(h[i]-h[A[i]]);
		sb[i][0]=0;
		sb[i][1]=abs(h[A[i]]-h[B[A[i]]]);
	}
	
	for(int j=2;j<=17;j++){
		for(int i=1;i<=n;i++){
			sa[i][j]=sa[i][j-1]+sa[f[i][j-1]][j-1];
			sb[i][j]=sb[i][j-1]+sb[f[i][j-1]][j-1];
		}
	}
	
	int x,id=0;
	double ans=1e15;
	
	cin>>x;
	for(int i=1;i<=n;i++){
		int la=0,lb=0,now=i,cnt=0;
		for(int j=17;j>=0;j--){
			if(!f[now][j] or la+lb+sa[now][j]+sb[now][j]>x)continue;
			la+=sa[now][j];
			lb+=sb[now][j];
			cnt+=1<<j;
			now=f[now][j];
		}
		if(lb!=0){
			if(fabs(double(la)/double(lb)-ans)<1e-9 and h[i]>h[id])id=i;
			if(double(la)/double(lb)<ans)ans=double(la)/double(lb),id=i;
		}
	}
	cout<<id<<endl;
	
	int q;cin>>q;
	
	while(q--){
		int now;
		cin>>now>>x;
		int la=0,lb=0,cnt=0;
		for(int j=17;j>=0;j--){
			if(!f[now][j] or la+lb+sa[now][j]+sb[now][j]>x)continue;
			la+=sa[now][j];
			lb+=sb[now][j];
			cnt+=1<<j;
			now=f[now][j];
		}
		cout<<la<<' '<<lb<<endl;
	}
	//Lappland ForEver
}
posted @ 2025-10-20 10:17  Noivelist  阅读(13)  评论(0)    收藏  举报