记录编号 197010 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2012]开车旅行 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 1.863 s
提交时间 2015-10-23 07:16:46 内存使用 60.98 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<set>
using namespace std;
typedef long long LL;
int g[100010][30]={0};//从i地走2^j轮后所在的位置
LL f[100010][30][2]={0};//A,B所走的距离
int N,M;
int next[100010][2]={0};//[0]代表最近的,[1]代表次近的
LL dist[100010][2]={0};
LL X;
int S;
int t;
class miku
{
public:
	LL H;
	int id;
	miku(){}
	bool operator < (const miku &b) const
	{
		return H<b.H;
	}
}H[100010];
set<miku> tr;
set<miku>::iterator it;
inline void update(miku x,miku y)
{
	LL tem=abs(x.H-y.H);
	int w=x.id,p=y.id;
	if(!next[w][0])
	{
		next[w][0]=p;
		dist[w][0]=tem;
	}
	else if(tem<dist[w][0]||(tem==dist[w][0]&&y.H<x.H))
	{
		next[w][1]=next[w][0];
		dist[w][1]=dist[w][0];
		next[w][0]=p;
		dist[w][0]=tem;
	}
	else if(!next[w][1]||tem<dist[w][1]||(tem==dist[w][1]&&y.H<x.H))
	{
		next[w][1]=p;
		dist[w][1]=tem;
	}
}
void work()
{
	for(int i=N;i>=1;i--)
	{
		tr.insert(H[i]);
		it=tr.find(H[i]);
		if(it!=tr.begin())
		{
			it--;
			update(H[i],*it);
			if(it!=tr.begin())
			{
				it--;
				update(H[i],*it);
				it++;
			}
			it++;
		}
		if(it!=tr.end())
		{
			it++;
			update(H[i],*it);
			if(it!=tr.end())
			{
				it++;
				update(H[i],*it);
			}
		}
	}
	for(int i=1;i<=N;i++)
	{
		g[i][0]=next[next[i][1]][0];
		f[i][0][0]=dist[i][1];
		f[i][0][1]=dist[next[i][1]][0];
	}
	t=int(trunc(log2(N)));
	for(int j=1;j<=t;j++)
		for(int i=1;i<=N;i++)
		{
			g[i][j]=g[g[i][j-1]][j-1];
			f[i][j][0]=f[i][j-1][0]+f[g[i][j-1]][j-1][0];
			f[i][j][1]=f[i][j-1][1]+f[g[i][j-1]][j-1][1];
		}
}
void get(int s,LL x,LL& dista,LL& distb)
{
	for(int i=t;i>=0;i--)
	{
		if(f[s][i][0]+f[s][i][1]<=x&&g[s][i])
		{
			dista+=f[s][i][0];
			distb+=f[s][i][1];
			x-=f[s][i][0]+f[s][i][1];
			s=g[s][i];
		}
	}
	if(next[s][1]&&dist[s][1]<=x)
		dista+=dist[s][1];
}
int main()
{
	freopen("drive.in","r",stdin);
	freopen("drive.out","w",stdout);
	scanf("%d",&N);
	int ans=0;
	for(int i=1;i<=N;i++)
	{
		scanf("%lld",&H[i].H);//提交时修改为lld
		H[i].id=i;
	}
	work();
	scanf("%lld",&X);//提交时修改为lld
	LL a=1e15,b=0;
	for(int i=1;i<=N;i++)
	{
		LL dista=0,distb=0;
		get(i,X,dista,distb);
		if(distb&&(ans==0||a*distb>b*dista))
		{
			ans=i;
			a=dista;
			b=distb;
		}
	}
	printf("%d\n",ans);
	scanf("%d",&M);
	//cout<<M<<endl;
	for(int i=1;i<=M;i++)
	{
		scanf("%d%lld",&S,&X);
		LL dista=0,distb=0;
		get(S,X,dista,distb);
		printf("%lld %lld\n",dista,distb);
		//if(i==14712) cout<<"*********************************"<<endl;
	}
	return 0;
}