题意:

给n个点的海拔h[i](不同点海拔不同) 两点的距离为abs(h[i]-h[j]) 有a、b两人轮流开车(只能往下标大的地方开) a每次会开到里当前点第二近的点 b每次会开到离当前点最近的点(距离相同h小的近) 给定x 如果a或b继续开距离和会大于x就不继续开。

求两个问题

1、给定x=x0求从哪点开始开能使a开的距离:b开的距离最小 不值相同取海拔高的

2、给出m个询问 每个询问给定x1、y1 求从x1开始走且x=y1 a能走的距离和b能走的距离

题解:

不难发现(其实我一开始没发现 看了题解才知道TAT)从固定某点i走到的后若干个点和x没关系

我们可以预处理出从i点走j个点 a、b走的距离 由于数据略大 可以用倍增做 move[i][j] 表示i开始走2^j步 a、b走的距离

由于n比较大 不能n^2直接算离某点最近和第二进的点是谁

可以先把所有的h[i]拿来排序 建立双向链表 显然i点的最近点一定是双向链表中i的前驱或后继 而次近点则还可能是前驱的前驱或后继的后继 每次求完将该点从双向链表中删除 这样就能o(n) 求出最近和次近点了

然后我们就可以倍增轻松求出i开始走 且a、b走的距离<=x a、b分别走了多远了(第二个问题解决)

对于第一个问题 也很简单 直接枚从哪个点开始走算ans就完了

代码:

 #include <cstdio>
#include <algorithm>
typedef long long ll;
using std::sort;
const ll N=;
struct info{
ll t,ma,mb,bo;
info(const ll a=,const ll b=,const ll c=,const ll d=):
t(a),ma(b),mb(c),bo(d){}
}move[N][][],save;
struct inli{
ll t,pr,ne;
inli(const ll a=,const ll b=,const ll c=):
t(a),pr(b),ne(c){}
}line[N];
struct inim{
ll t,s;
inim(const ll a=,const ll b=):
t(a),s(b){}
}im[N];
inline bool cmp(inim x,inim y){ return x.t<y.t; }
ll h[N],sp[N],n,m,x0,ans;
void makeline(){
for (ll i=;i<=n;i++){
line[i].t=im[i].s;
if (i>) line[i].pr=i-;
if (i<n) line[i].ne=i+;
}
}
void makeres(ll &res1,ll &res2,ll t,ll a1){
if (!a1) return;
if (res1== || abs(h[t]-h[a1])<abs(h[t]-h[res1]) ||
(abs(h[t]-h[a1])==abs(h[t]-h[res1]) && h[a1]<h[res1])) res2=res1,res1=a1;
else if (res2== || abs(h[t]-h[a1])<abs(h[t]-h[res2]) ||
(abs(h[t]-h[a1])==abs(h[t]-h[res2]) && h[a1]<h[res2])) res2=a1;
}
inim getmove(ll t,ll a1,ll a2,ll a3,ll a4){
ll res1=,res2=;
if (t==)
t=;
makeres(res1,res2,t,line[a1].t);
makeres(res1,res2,t,line[a2].t);
makeres(res1,res2,t,line[a3].t);
makeres(res1,res2,t,line[a4].t);
if (!res1) return inim(res2,res1);
return inim(res1,res2);
}
void makemove0(){
for (ll i=;i<n;i++){
if (i==)
i=;
inim x=getmove(i,line[sp[i]].pr,line[sp[i]].pr ? line[line[sp[i]].pr].pr : ,
line[sp[i]].ne,line[sp[i]].ne ? line[line[sp[i]].ne].ne : );
move[i][][].t=x.t;
move[i][][].ma=abs(h[i]-h[x.t]);
move[i][][].bo=;
if (x.s){
move[i][][].t=x.s;
move[i][][].mb=abs(h[i]-h[x.s]);
move[i][][].bo=;
}
line[line[sp[i]].pr].ne=line[sp[i]].ne;
line[line[sp[i]].ne].pr=line[sp[i]].pr;
}
}
void makemove(){
makemove0();
for (ll i=n;i;i--)
for (ll k=;k<=;k++){
if (i==)
i=;
for (ll j=;move[move[i][j-][k].t][j-][move[i][j-][k].bo].t;j++){
info x=move[move[i][j-][k].t][j-][move[i][j-][k].bo];
move[i][j][k].t=x.t;
move[i][j][k].bo=x.bo;
move[i][j][k].ma=move[i][j-][k].ma+x.ma;
move[i][j][k].mb=move[i][j-][k].mb+x.mb;
}
}
}
info getans(ll x,ll y){
info res=info(x,,,);
for (;y>=move[res.t][][res.bo].ma+move[res.t][][res.bo].mb && move[res.t][][res.bo].t;){
ll i=,st=res.t,sb=res.bo;
while (y>=move[st][i][sb].ma+move[st][i][sb].mb && move[st][i][sb].t) ++i;
--i;
y-=move[st][i][sb].ma+move[st][i][sb].mb;
res.t=move[st][i][sb].t;
res.bo=move[st][i][sb].bo;
res.ma+=move[st][i][sb].ma;
res.mb+=move[st][i][sb].mb;
}
return res;
}
bool check(info x,ll y){
if (!ans) return ;
if (!x.ma){
if (save.ma) return ;
else return (h[y]>h[ans]);
}
if (!save.mb) return ;
if (save.ma*x.mb<save.mb*x.ma || (save.ma*x.mb==save.mb*x.ma && h[y]>h[ans])) return ;
else return ;
}
int main(){
freopen("drive.in","r",stdin);
freopen("drive.out","w",stdout);
scanf("%I64d",&n);
for (ll i=;i<=n;i++){
scanf("%I64d",&h[i]);
im[i]=inim(h[i],i);
}
sort(im+,im+n+,cmp);
for (ll i=;i<=n;i++) sp[im[i].s]=i;
makeline();
makemove();
scanf("%I64d",&x0);
for (ll i=;i<=n;i++){
info x=getans(i,x0);
if (check(x,i)) save=x,ans=i;
}
printf("%I64d\n",ans);
scanf("%I64d",&m);
ll x,y;
for (ll i=;i<=m;i++){
if (i==)
i=;
scanf("%I64d%I64d",&x,&y);
info xx=getans(x,y);
printf("%I64d %I64d\n",xx.mb,xx.ma);
}
fclose(stdin);
fclose(stdout);
}

【noip2012】开车旅行的更多相关文章

  1. Cogs 1264. [NOIP2012] 开车旅行(70分 暴力)

    1264. [NOIP2012] 开车旅行 ★★☆   输入文件:drive.in   输出文件:drive.out   简单对比时间限制:2 s   内存限制:128 MB [题目描述] 小A 和小 ...

  2. P1081 [NOIP2012]开车旅行[倍增]

    P1081 开车旅行    题面较为啰嗦.大概概括:一个数列,只能从一个点向后走,两种方案:A.走到和自己差的绝对值次小的点B.走到和自己差的绝对值最小点:花费为此差绝对值:若干询问从规定点向后最多花 ...

  3. noip2012开车旅行 题解

    题目大意: 给出n个排成一行的城市,每个城市有一个不同的海拔.定义两个城市间的距离等于他们的高度差的绝对值,且绝对值相等的时候海拔低的距离近.有两个人轮流开车,从左往右走.A每次都选最近的,B每次都选 ...

  4. NOIP2012开车旅行 【倍增】

    题目 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为Hi,城市 i 和城 ...

  5. Luogu 1081 [NOIP2012] 开车旅行

    感谢$LOJ$的数据让我调掉此题. 这道题的难点真的是预处理啊…… 首先我们预处理出小$A$和小$B$在每一个城市的时候会走向哪一个城市$ga_i$和$gb_i$,我们有链表和平衡树可以解决这个问题( ...

  6. noip2012 开车旅行

    此题100分的解法就是先预处理出每个点的下一个点之后倍增就好了.其实并没有太大难度. pbihao用双向链表写过了此题.在本地上我treap狂操他,but在rqnoj上,我依靠反复提交才A掉此题(最后 ...

  7. Luogu1081 NOIP2012 开车旅行 倍增

    题目传送门 为什么NOIP的题目都这么长qwq 话说2012的D1T3和D2T3都是大火题啊qwq 预处理神题 对于这种跳跳跳的题目考虑使用倍增优化枚举.先预处理某个点之后距离最小和次小的城市,然后倍 ...

  8. luogu1081 [NOIp2012]开车旅行 (STL::multiset+倍增)

    先用不管什么方法求出来从每个点出发,A走到哪.B走到哪(我写了一个很沙雕的STL) 然后把每个点拆成两个点,分别表示A从这里出发和B从这里出发,然后连边是要A连到B.B连到A.边长就是这次走的路径长度 ...

  9. 洛谷1081 (NOIp2012) 开车旅行——倍增预处理

    题目:https://www.luogu.org/problemnew/show/P1081 预处理从每个点开始a能走多少.b能走多少.可以像dp一样从后往前推. 但有X的限制.所以该数组可以变成倍增 ...

  10. Luogu 1081 【NOIP2012】开车旅行 (链表,倍增)

    Luogu 1081 [NOIP2012]开车旅行 (链表,倍增) Description 小A 和小B决定利用假期外出旅行,他们将想去的城市从1到N 编号,且编号较小的城市在编号较大的城市的西边,已 ...

随机推荐

  1. Making your local server accessible from anywhere

    In reality you probably don’t want to host you websites on your local computer unless you have a ver ...

  2. c++内存中字节对齐问题详解

    一.什么是字节对齐,为什么要对齐?    现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址 ...

  3. hdu 4658 Integer Partition

    五角数定理!!可以参考这个http://www.cnblogs.com/xin-hua/p/3242428.html  代码如下: #include<iostream> #include& ...

  4. 缺少编译器要求的成员“System.Runtime.CompilerServices.ExtensionAttribute..ctor” 解决方案

    静态类中添加如下.此方法本人测试有效. //缺少编译器要求的成员“ystem.Runtime.CompilerServices.ExtensionAttribute..ctor” namespace  ...

  5. dtp--eclipse的安装数据源管理的一个插件的安装方法

    1.  下载eclipse dtp 插件 http://download.eclipse.org/datatools/updates/1.11 help——>install new softwa ...

  6. http://jingyan.baidu.com/article/7908e85c74d85faf491ad260.html

    http://jingyan.baidu.com/article/7908e85c74d85faf491ad260.html

  7. 基于ASP.NET的comet简单实现

    http://www.cnblogs.com/hanxianlong/archive/2010/04/27/1722018.html 我潜水很多年,今天忽然出现.很久没写过博客了,不是因为不想写,而是 ...

  8. SOCKS5协议

    SOCKS5 是一个代理协议,这种协议对本身所代理的内容并不关心,可用于穿越防火墙. 例如我有一台web服务器,用户可以登陆上去查询公司的关键数据,这样的服务器我肯定是不想放到公网上让别人能随便访问, ...

  9. WPF控件模板和数据模板

    来自:http://www.th7.cn/Program/WPF/2011/12/21/51676.shtml ControlTemplate用于描述控件本身. 使用TemplateBinding来绑 ...

  10. 无效的 URI: 未能分析证书颁发机构/主机

    出 现该错误的原因是URL中少了一个斜杠,正常的URL是“http:”后边有两个斜杠,而我在修改配置文件中的URL的IP地址部分时,不小心删掉了一个 斜杠,例如:http:/blog.csdn.net ...