记录编号 315972 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2012]开车旅行 最终得分 100
用户昵称 Gravatar可以的. 是否通过 通过
代码语言 C++ 运行时间 3.733 s
提交时间 2016-10-06 07:46:42 内存使用 50.25 MiB
显示代码纯文本
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#include <cstring>
using namespace std;
#define E puts("")
const int maxn = 110000;
typedef long long LL;
const double INF = 5000000000LL;
const double eps = 1e-10;
int dcmp(double x){
	if(fabs(x) < eps) return 0;
	return x < 0 ? -1 : 1;	
}
int n,m;
struct City
{
	int num,h;	
	bool operator < (const City &b)const
	{
		return h < b.h;	
	}
}c[maxn];
set < City > q;
set < City > :: iterator it;
#define read(x) scanf("%d",&x)
void Read_one(){
	read(n);
	for(int i=1;i<=n;i++){	
		read(c[i].h); c[i].num = i;	
	}
}
struct Temp // 暂时存储i城市的next 
{
	int num,dif;
	bool operator < (const Temp &b)const
	{
		if(dif != b.dif) return dif < b.dif;
		return c[num].h < c[b.num].h;	
	}
}t[5]; 
int nexta[maxn],nextb[maxn];
void Find_next(int i){
	it = q.find(c[i]);
	int _t = 0;
	if(it != q.begin()){
		it -- ;
		t[++_t] = (Temp){ (*it).num , abs((*it).h - c[i].h) };
		if(it != q.begin()){
			it -- ;
			t[++_t] = (Temp){ (*it).num , abs((*it).h - c[i].h) };	
			it ++ ;
		}
		it ++ ;
	}
	if((++it) != q.end()){
		t[++_t] = (Temp){ (*it).num , abs((*it).h - c[i].h) };
		if((++it) != q.end()){
			t[++_t] = (Temp){ (*it).num , abs((*it).h - c[i].h) };
		}
	}
	sort(t + 1,t + 1 + _t);
	nextb[i] = t[1].num; if(_t == 1) return;
	nexta[i] = t[2].num;
}
void Prepare_next(){
	for(int i=n;i>0;i--){
		q.insert(c[i]);
		if(i != n) Find_next(i);
	}	
	/*
	puts("next : ");
	for(int i=1;i<=n;i++){
		printf("A = %d  B = %d\n",nexta[i],nextb[i]);	
	}E;
	*/
}
LL fa[maxn][23],fb[maxn][23];
int f[maxn][23];
void Prepare_f(){
	for(int i=1;i<=n;i++){
		int pos1 = nexta[i], pos2 = nextb[nexta[i]];
		//从i出发走1轮
		fa[i][0] = pos1 ? abs(c[pos1].h - c[i].h) : 0;
		fb[i][0] = pos2 ? abs(c[pos2].h - c[pos1].h) : 0;
		f[i][0] = pos2; // 最后停在pos2	
	}
	for(int j=1;j<20;j++){
		for(int i=1;i<=n;i++){
			f[i][j] = f[f[i][j-1]][j-1];
			fa[i][j] = fa[i][j-1] + fa[f[i][j-1]][j-1];
			fb[i][j] = fb[i][j-1] + fb[f[i][j-1]][j-1];
		} 
	}
}
int x0,ans=0;
LL da = 0 , db = 0;

double Query(int St,int X){
//	printf("S = %d  : ",St);
	da = 0; db = 0;
	for(int i=20;i>=0;i--){
		if(f[St][i] && fa[St][i] + fb[St][i] <= X){
			da += (LL)fa[St][i];  db += (LL)fb[St][i];
			X -= fa[St][i] + fb[St][i];
			St = f[St][i];
		}	
	}
	int posa=nexta[St];
	if(posa){
		LL dis = abs(c[posa].h - c[St].h);
		if(dis <= X) da += dis;
	}
	if(!db) return INF;
	else return ((long double)da/(long double)db);
}
void calc_one(){
	cin >> x0; ans = 0;
	double Min = 1e100;
	for(int i=1;i<=n;i++){
		double temp = Query(i,x0);
		if(dcmp(Min - temp) > 0 || (!dcmp(Min - temp) && c[ans].h < c[i].h)){
			Min = temp ; ans = i;
		}
	}
	printf("%d\n",ans);
}
void calc_two(){
	cin >> m;
	while(m -- ){
		int si,xi; cin >> si >> xi;
		double temp = Query(si,xi);
		printf("%lld %lld\n",da,db);
	}
}
void lala();
int main(){
	freopen("drive.in","r",stdin);freopen("drive.out","w",stdout);
	Read_one();
	Prepare_next();
	Prepare_f();
	calc_one();
	calc_two();
	return 0;
	//lala();
	for(;;);
}
void lala(){
	double X,Y;
	while(scanf("%lf%lf",&X,&Y)==2){
		printf("%d\n",dcmp(X - Y));	
	}
}

/*
5
-1000000000 0 -999999999 999999999 1000000000
1000000000
7
1 1000000000
2 1000000000
3 1000000000
4 1000000000
5 1000000000
1 2
2 3

2

*/