noip 2012 开车旅行

时间:2022-04-22 20:04:29
/*考场上写的暴力 40分钟70分*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define base 1000000000
#define maxn 100010
#define ll long long
using namespace std;
ll n,m,h[maxn],X,A[maxn],B[maxn],st,ans;
bool falg;
double mii=base;
ll init()
{
ll x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
ll Abs(ll a)
{
return a<?-a:a;
}
void Get_AB()
{
for(int i=;i<=n;i++)
{
ll mxx,mx,mxxh,mxh,kxx=,kx=;mxx=mx=0x7fffffff;
for(int j=i+;j<=n;j++)
{
ll C=Abs(h[i]-h[j]);
if(C<mxx||(C==mxx&&h[j]<mxxh))
mx=mxx,mxx=C,mxh=mxxh,mxxh=h[j],kx=kxx,kxx=j;
else if((C==mxx&&h[j]>=mxxh)||C<mx||(C==mx&&h[j]<mxh))
mx=C,mxh=h[j],kx=j;
}
A[i]=kx;B[i]=kxx;
}
}
void Dfs(ll now,ll who,ll As,ll Bs,ll limit,ll S)
{
if(falg)return;ll s1=,s2=;double tmp;
if(!who)s1=As+Abs(h[now]-h[A[now]]),S+=Abs(h[now]-h[A[now]]);
if(who)s2=Bs+Abs(h[now]-h[B[now]]),S+=Abs(h[now]-h[B[now]]);
if(S>limit||(!who&&A[now]==)||(who&&B[now]==))
{
if(!Bs)tmp=base;
else tmp=double(As)/double(Bs);
if(tmp<mii||(tmp==mii&&h[st]>h[ans]))
ans=st,mii=tmp;
falg=;return ;
}
if(!who&&s1<=limit)Dfs(A[now],!who,s1,Bs,limit,S);if(falg)return;
if(who&&s2<=limit)Dfs(B[now],!who,As,s2,limit,S);if(falg)return;
if(!Bs)tmp=base;
else tmp=double(As)/double(Bs);
if(tmp<mii||(tmp==mii&&h[st]>h[ans]))
ans=st,mii=tmp;
falg=;return ;
}
void dfs(ll now,ll who,ll As,ll Bs,ll limit,ll S)
{
if(falg)return;ll s1=,s2=;
if(!who)s1=As+Abs(h[now]-h[A[now]]),S+=Abs(h[now]-h[A[now]]);
if(who)s2=Bs+Abs(h[now]-h[B[now]]),S+=Abs(h[now]-h[B[now]]);
if(S>limit||(!who&&A[now]==)||(who&&B[now]==))
{
cout<<As<<" "<<Bs<<endl;
falg=;return;
}
if(!who&&s1<=limit)dfs(A[now],!who,s1,Bs,limit,S);if(falg)return;
if(who&&s2<=limit)dfs(B[now],!who,As,s2,limit,S);if(falg)return;
cout<<As<<" "<<Bs<<endl;
falg=;return;
}
int main()
{
n=init();int x,s;
for(int i=;i<=n;i++)
{
x=init();h[i]=x+base;
}
Get_AB();X=init();
for(int i=;i<=n;i++)
falg=,st=i,Dfs(i,,,,X,);
cout<<ans<<endl;
m=init();
for(int i=;i<=m;i++)
{
s=init();x=init();
falg=;dfs(s,,,,x,);
}
return ;
}
/*
暴力的复杂度是n*n的
首先预处理每个点的最短次短距离就Tle了
这里我们借助set O n 的解决这个问题
然后对于每个询问 利用倍增 logn的实现就不超时了
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<cmath>
#define base 100000000000//大大大大大
#define maxn 100010
#define ll long long
using namespace std;
ll n,m,X,A[maxn],B[maxn],As[maxn],Bs[maxn],ans;
ll d[maxn][],f[maxn][][];
double mii=base;
struct point
{
ll o,hi;
bool operator < (const point & a) const
{
return hi<a.hi;
}
}p[maxn];
set<point>s;
set<point>::iterator pi;
ll init()
{
ll x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
ll abs(ll a)
{
return a<?-a:a;
}
void Add(point x,point y)
{
if(!B[x.o])
{
B[x.o]=y.o;
Bs[x.o]=abs(x.hi-y.hi);
}
else if(abs(x.hi-y.hi)<Bs[x.o]||(abs(x.hi-y.hi)==Bs[x.o]&&y.hi<p[B[x.o]].hi))
{
A[x.o]=B[x.o];
As[x.o]=Bs[x.o];
B[x.o]=y.o;
Bs[x.o]=abs(x.hi-y.hi);
}
else if(abs(x.hi-y.hi)<As[x.o]||(abs(x.hi-y.hi)==As[x.o]&&y.hi<p[A[x.o]].hi))
{
A[x.o]=y.o;
As[x.o]=abs(x.hi-y.hi);
}
else if(!A[x.o])
{
A[x.o]=y.o;
As[x.o]=abs(x.hi-y.hi);
}
return;
}
void Get_AB()
{
for(int i=n;i>=;i--)
{
s.insert(p[i]);
pi=s.find(p[i]);
if(pi!=s.begin())
{
pi--;Add(p[i],*pi);
if(pi!=s.begin())
{
pi--;Add(p[i],*pi);pi++;
}
pi++;
}
if((++pi)!=s.end())
{
Add(p[i],*pi);
if((++pi)!=s.end())
Add(p[i],*pi);
pi--;
}
pi--;
}
}
void Query(int st,ll limit,ll & sa,ll & sb)
{
for(int i=;i>=;i--)
if(f[st][i][]+f[st][i][]<=limit&&d[st][i])
{
sa+=f[st][i][];sb+=f[st][i][];
limit-=(f[st][i][]+f[st][i][]);st=d[st][i];
}
if(A[st]&&As[st]<=limit)
sa+=As[st];
}
int main()
{
n=init();
for(int i=;i<=n;i++)
{
p[i].hi=init();p[i].o=i;
}
Get_AB();
for(int i=;i<=n;i++)
{
d[i][]=B[A[i]];
f[i][][]=As[i];
f[i][][]=Bs[A[i]];
}
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
{
d[i][j]=d[d[i][j-]][j-];
f[i][j][]=f[i][j-][]+f[d[i][j-]][j-][];
f[i][j][]=f[i][j-][]+f[d[i][j-]][j-][];
}
X=init();
for(int i=;i<=n;i++)
{
ll sa=,sb=;double tmp;
Query(i,X,sa,sb);
if(!sb)tmp=base;
else tmp=double(sa)/double(sb);
if(tmp<mii||(tmp==mii&&p[i].hi>p[ans].hi))
ans=i,mii=tmp;
}
cout<<ans<<endl;
m=init();int st;
for(int i=;i<=m;i++)
{
st=init();X=init();
ll sa=,sb=;
Query(st,X,sa,sb);
cout<<sa<<" "<<sb<<endl;
}
return ;
}