开车旅行(NOIP2012)
这道坑爹题调了我2小时233~
首先这道题可以用set,平衡树,双向链表等一堆非(sang)常(xin)简(bing)单(kuang)的算法搞出对于任何一个高度h[i]的前2名和后2名
然后我们看到这个
就想到了倍增。。。
但是调不出来o(≧口≦)o
还要特判一下A走后B就不走了的情况。。(用va[i][0]表示)
然后第一问O(N)。。第二问O(M)
最后在黄学长的blog的帮助之下才调了出来。。
真是zxyer说的纯模拟大水比题目啊(233~)
简直跟A*八数码有的一拼。。
下面贴代码
#include<iostream>
#include<set>
#include<map>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define inf 5000000000LL
using namespace std;
int h[100005];
int fa[100005],fb[100005];
long long a[100005],b[100005],va[100005][17],vb[100005][17],to[100005][17];
int n,m;
struct data{
long long key,h;
}t[5];
inline bool operator<(data a,data b)
{
return a.key<b.key||(a.key==b.key&&a.h<b.h);
}
set <long long> q;
map <long long,int> mp;
void pre(){
for(int i=n;i;i--)
{
q.insert(h[i]);
t[1].h=*--q.lower_bound(h[i]);t[2].h=*q.upper_bound(h[i]);
if(t[1].h!=-inf)t[3].h=*--q.lower_bound(t[1].h);
else t[3].h=-inf;
if(t[2].h!=inf)t[4].h=*q.upper_bound(t[2].h);
else t[4].h=inf;
for(int k=1;k<=4;k++)
t[k].key=abs(t[k].h-h[i]);
sort(t+1,t+5);
a[i]=t[2].key;fa[i]=mp[t[2].h];
b[i]=t[1].key;fb[i]=mp[t[1].h];
for(int j=0;j<=16;j++)
if(j==0)
{
if(fa[i]){va[i][0]=a[i];to[i][0]=fa[i];}
}
else if(j==1)
{
if(fb[fa[i]]){va[i][1]=a[i];vb[i][1]=b[fa[i]];to[i][1]=fb[fa[i]];}
}
else
if(to[to[i][j-1]][j-1])
{
va[i][j]=va[i][j-1]+va[to[i][j-1]][j-1];
vb[i][j]=vb[i][j-1]+vb[to[i][j-1]][j-1];
to[i][j]=to[to[i][j-1]][j-1];
}
else break;
}
}
double cal1(int x,int val)
{
int t1=0,t2=0;
for(int i=16;i>=0;i--)
if(to[x][i]&&t1+va[x][i]+vb[x][i]+t2<=val)
{
t1+=va[x][i];t2+=vb[x][i];
x=to[x][i];
}
if(t2==0)return inf;
return (double)t1/(double)t2;
}
void cal2(int x,int val)
{
int t1=0,t2=0;
for(int i=16;i>=0;i--)
if(to[x][i]&&t1+va[x][i]+vb[x][i]+t2<=val)
{
t1+=va[x][i];
t2+=vb[x][i];
x=to[x][i];
}
printf("%d %d\n",t1,t2);
}
void solve1(){
double mn=1e60;int ans;
int num;
scanf("%d",&num);
for(int i=1;i<=n;i++)
{
double t=cal1(i,num);
if(t<mn||t==mn&&h[i]>h[ans])
{
mn=t;
ans=i;
}
}
printf("%d\n",ans);
}
void solve2(){
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int s,x;
scanf("%d%d",&s,&x);
cal2(s,x);
}
}
int main(){
scanf("%d",&n);
q.insert(-inf);q.insert(inf);
for(int i=1;i<=n;i++)
{
scanf("%d",&h[i]);
mp[h[i]]=i;
}
pre();
solve1();
solve2();
return 0;
}

浙公网安备 33010602011771号