这道题:你不仅要学会两人交换开车,还要做到高效驾驶。

·分析:

      在拨开花哨题目的迷雾之后,发现两个重要突破口:

      ①从每个点开始,他们的路径是一定的,不存在决策选取。

      ②要是n,m没有那么大的话,就直接预处理每个点对于每个人开车至下一个点的位置和路程(n2),然后两个问题都可以从起点(第一问就是枚举起点)开始预处理的数据来“轮流开车”。(这一个突破口有点过于顶尖了,因为这是过70%数据的题解)

      下图是这种做法的简图。

      用des[i][0],des[i][1]分别表示在城市i小B开车和小A开车前往的下一个目的地。用Min[i][0],Min[i][1]分别与上面的数组对应,表示对应路径的长度(注意是反向枚举)

·无论是第一问还是第二问,都可以从起点s开始,通过des,Min数组来向后开车并记录两人各自走的路程。

·很美妙但又很遗憾,仅仅这样做时间复杂度:(n2+nm)

·这道题真正的考点就出来了:考察我们的优化技能。

·很轻易可以发现,这道题的数据范围又给了我们很大的提示:

n<=100000。这启示我们:nlogn

·余下的事情就是把时间复杂度中的部分n替换成logn,使得时间复杂度保持在:O(mlogn+nlogn)【这有点过于顶尖了】

·在本题中大米饼的对策是:预处理des,Min(这原来是一个n2)时使用STL中的set来维护(降为nlogn),在路径上使用倍增法,

·最后一个值得注意的一点,倍增的每一段为了方便操作,这里AB各走一次算成一段,不过倍增的距离还是对AB进项单独维护。整个程序还有许多细节需要注意。 wow!

 #include<stdio.h>
#include<algorithm>
#include<set>
#define go(i,a,b) for(int i=a;i<=b;i++)
#define ro(i,a,b) for(int i=a;i>=b;i--)
#define inf 2147483645
#define eps 0.000003
using namespace std;const int N=;
int n,m,s,h[N],des[N][],Min[N][],To[N][],dis[N][][],tot[],x;
struct info{int h,id;bool operator<(const info a)const{return h<a.h;};};
set<info>box;set<info>::iterator I;int A(int t){return t<?-t:t;}
void consider(int i,info p)
{
int j=p.id;
if((A(h[i]-h[j])<Min[i][])||(Min[i][]==A(h[i]-h[j])&&h[j]<h[des[i][]]))
{
if((Min[i][]<Min[i][])||(Min[i][]==Min[i][]&&h[des[i][]]<h[des[i][]]))
Min[i][]=Min[i][],des[i][]=des[i][];
Min[i][]=A(h[i]-h[j]),des[i][]=j;
}
else if((A(h[i]-h[j])<Min[i][])||(Min[i][]==A(h[i]-h[j])&&h[j]<h[des[i][]]))
Min[i][]=A(h[i]-h[j]),des[i][]=j;
}
void doubling(int i,int val)
{
ro(k,,)if(dis[i][k][]+dis[i][k][]<=val&&To[i][k])
val-=(dis[i][k][]+dis[i][k][]),
tot[]+=dis[i][k][],tot[]+=dis[i][k][],i=To[i][k];
if(des[i][]&&Min[i][]<=val)tot[]+=Min[i][];
}
int main(){scanf("%d",&n);go(i,,n)scanf("%d",&h[i]),Min[i][]=Min[i][]=inf;
ro(i,n,)
{
box.insert((info){h[i],i});
I=box.find((info){h[i],i});++I;
if(I!=box.end())consider(i,*I),++I,I!=box.end()?consider(i,*I),:,--I;--I;
if(I!=box.begin())--I,consider(i,*I),I!=box.begin()?--I,consider(i,*I),:;
} go(i,,n)To[i][]=des[des[i][]][],
dis[i][][]=Min[i][],dis[i][][]=Min[des[i][]][]; go(k,,)go(i,,n)To[i][k]=To[To[i][k-]][k-],
dis[i][k][]=dis[i][k-][]+dis[To[i][k-]][k-][],
dis[i][k][]=dis[i][k-][]+dis[To[i][k-]][k-][]; scanf("%d",&x);double rate=inf;int pos=;h[]=-inf;go(i,,n)
{
tot[]=tot[]=;doubling(i,x);double tmp=tot[]?1.0*tot[]/tot[]:inf;
if(tmp-rate<eps&&tmp-rate>-eps&&h[i]>h[pos])pos=i;
if(rate-tmp>eps)pos=i,rate=tmp;
} printf("%d\n",pos);scanf("%d",&m);go(i,,m)
{
scanf("%d%d",&s,&x);
tot[]=tot[]=;doubling(s,x);
printf("%d %d\n",tot[],tot[]);
}
return ;
}//Paul_Guderian

只许集中,不许分散。————海因茨·威廉·古德里安

【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. Django Haystack 全文检索与关键词高亮

    Django Haystack 简介 django-haystack 是一个专门提供搜索功能的 django 第三方应用,它支持 Solr.Elasticsearch.Whoosh.Xapian 等多 ...

  2. iOS开发所有KeyboardType与图片对应展示

    1.UIKeyboardTypeAlphabet 2.UIKeyboardTypeASCIICapable 3.UIKeyboardTypeDecimalPad  4.UIKeyboardTypeDe ...

  3. 16-TypeScript装饰器模式

    在客户端脚本中,有一个类通常有一个方法需要执行一些操作,当我们需要扩展新功能,增加一些操作代码时,通常需要修改类中方法的代码,这种方式违背了开闭的原则. 装饰器模式可以动态的给类增加一些额外的职责.基 ...

  4. XML之XPath

    1.在 XPath 中,有七种类型的节点:元素.属性.文本.命名空间.处理指令.注释以及文档节点(或称为根节点). 1.1 XPath 术语 节点(Node) 在 XPath 中,有七种类型的节点:元 ...

  5. leetcode算法:Trim a Binar Search Tree

    Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that a ...

  6. python/零起点(一、字符串)

    python/零起点(一.字符串) 字符串(str) 字符串是可迭代的 str()强制转成字符串类型 字符串是有序的,且不可变的数据类型. 字符串转换整型的案例: 1 name=['guobaoyua ...

  7. Java:Java 中会存在内存泄漏吗

    理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因):然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致 ...

  8. Django:(博客系统)添加文章(中文)出现UnicodeEncodeError乱码

    添加文章时出现了一个UnicodeEncodeError乱码问题 在添加文章时,抛出了异常: 解决方案,修改manage.py(添加import sys reload(sys) sys.setdefa ...

  9. 南京邮电大学java程序设计作业在线编程第三次作业

    王利国的"Java语言程序设计第3次作业(2018)"详细 作业结果详细 总分:100 选择题得分:60  1. 设有如下定义语句: String s1="My cat& ...

  10. hdu4864 Task贪心好题

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4864 题目大意: 有n个机器,m个任务.每个机器至多能完成一个任务.对于每个机器,有一个最大运行时间 ...