题目传送门

为什么NOIP的题目都这么长qwq


话说2012的D1T3和D2T3都是大火题啊qwq

预处理神题

对于这种跳跳跳的题目考虑使用倍增优化枚举。先预处理某个点之后距离最小和次小的城市,然后倍增预处理一大堆东西。设$f_i$表示从$A$开始开$2^i$次车到达的地点,$g_i$表示从$B$开始开$2^i$次车到达的地点,$k_{i,0/1}$表示从$A$开始开$2^i$次车$A$或$B$经过的路程,$l_{i,0/1}$表示从$B$开始开$2^i$次车$A$或$B$经过的路程。注意边界与越界情况的处理。

接下来就可以直接拼凑法跳了,时间复杂度$O((n+q)logn)$

 #include<bits/stdc++.h>
 #define MAXN 100001
 using namespace std;
 inline int read(){
      , k = ;
     char c = getchar();
     while(!isdigit(c) && c != '-')  c = getchar();
     if(c == '-')    k = -k , c = getchar();
     ) + a + (c ^ ') , c = getchar();
     return a * k;
 }
 ][] , lb[MAXN][][];
 ][] , h[MAXN] , N;
 set < pair < int , int > > s;
 inline  ? a : -a;}
 pair < int , int > cul(int ss , int x){
     pair <  , );
     ) ; i >=  ; i--)
         ] && (] + lb[ss][i][] <= x){
             t.first += la[ss][i][];
             t.second += lb[ss][i][];
             ss = f[ss][i][];
         }
     return t;
 }
 int main(){
     memset(la ,  ,  , sizeof(lb));
     N = read();
      ; i <= N ; i++)   h[i] = read();
     s.insert(make_pair(h[N] , N));
     s.insert(make_pair(h[N - ] , N - ));
     )   f[N - ][][] = N;
      ; i ; i--){
         set < pair < int , int > > :: iterator t = s.insert(make_pair(h[i] , i)).first;
         if(t == s.begin()){
             f[i][][] = (++s.begin())->second;
             f[i][][] = (++++s.begin())->second;
             continue;
         }
         set < pair < int , int > > :: iterator t1 = --t , t2 = ++++t;
         if(t2 == s.end()){
             f[i][][] = t1->second;
             f[i][][] = (--t1)->second;
         }
         else{
             if(h[i] - t1->first <= t2->first - h[i]){
                 f[i][][] = t1->second;
                 if(t1 == s.begin()){
                     f[i][][] = t2->second;
                     continue;
                 }
                 --t1;
             }
             else{
                 f[i][][] = t2->second;
                 if(++t2 == s.end()){
                     f[i][][] = t1->second;
                     continue;
                 }
             }
             ][] = t1->second;
             ][] = t2->second;
         }
     }
      ; i <= N ; i++){
         ][])  la[i][][] = abs(h[i] - h[f[i][][]]);
         ][])  lb[i][][] = abs(h[i] - h[f[i][][]]);
         la[i][][] = lb[i][][] = ;
     }
      ; i < N ; i++){
         f[i][][] = f[f[i][][]][][];
         f[i][][] = f[f[i][][]][][];
         la[i][][] = la[i][][];
         lb[i][][] = lb[f[i][][]][][];
         la[i][][] = la[f[i][][]][][];
         lb[i][][] = lb[i][][];
     }
      ;  << i < N ; i++)
          ; j <= N - ( << i) ; j++){
             f[j][i][] = f[f[j][i - ][]][i - ][];
             f[j][i][] = f[f[j][i - ][]][i - ][];
             la[j][i][] = la[j][i - ][] + la[f[j][i - ][]][i - ][];
             lb[j][i][] = lb[j][i - ][] + lb[f[j][i - ][]][i - ][];
             la[j][i][] = la[j][i - ][] + la[f[j][i - ][]][i - ][];
             lb[j][i][] = lb[j][i - ][] + lb[f[j][i - ][]][i - ][];
         }
     ;
     pair <  , X0);
      ; i <= N ; i++){
         pair < int , int > t = cul(i , X0);
         ){
             maxN = t;
             dir = i;
         }
          && t.second ==  && h[dir] < h[i]){
             maxN = t;
             dir = i;
         }
         else    if(t.second && ((long long)maxN.first * t.second > (long long)maxN.second * t.first || maxN.first * t.second == maxN.second * t.first && h[dir] < h[i])){
             maxN = t;
             dir = i;
         }
     }
     printf("%d\n" , dir);
     for(X0 = read() ; X0 ; X0--){
         int a = read() , b = read();
         pair < int , int > t = cul(a , b);
         printf("%d %d\n" , t.first , t.second);
     }
     ;
 }

Luogu1081 NOIP2012 开车旅行 倍增的更多相关文章

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

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

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

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

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

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

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

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

  5. $Noip2012\ Luogu1081$ 开车旅行 倍增优化$ DP$

    Luogu Description Sol 1.发现对于每个城市,小A和小B的选择是固定的,可以预处理出来,分别记为ga[],gb[] 2.并且,只要知道了出发城市和出发天数,那么当前城市和小A,小B ...

  6. 【vijos1780】【NOIP2012】开车旅行 倍增

    题目描述 有\(n\)个城市,第\(i\)个城市的海拔为\(h_i\)且这\(n\)个城市的海拔互不相同.编号比较大的城市在东边.两个城市\(i,j\)之间的距离为\(|h_i-h_j|\) 小A和小 ...

  7. NOIP2012开车旅行 【倍增】

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

  8. 【NOIP2012提高组】开车旅行 倍增

    题目分析 朴素的做法就是预处理下一个目的地,然后跑模拟,超时. 本题最重要的考点是倍增优化.设$fa[i][j]$表示a从i出发行驶$2^j$“次”后行驶的路程,$fb[i][j]$表示从i出发行驶$ ...

  9. noip2012开车旅行 题解

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

随机推荐

  1. TFS 安装遇到的问题

    居然是是微信桌面客户端占用了8080端口,也是醉了... 1 VS链接 源码管理器 发现提示 Http 404, 发现原来是自己吧tfs 给删除了 2 重新安装tfs,过程中提示 8080 端口被占用 ...

  2. 微软 WPC 2014 合作伙伴keynote

    本周一,2014 微软WPC (Worldwide Partner Conference) 合作者伙伴大会在美国华盛顿开幕,微软除了介绍了Azure.云端化的Office 365和Windows Ph ...

  3. loadrunner 结果分析-loadrunner结果分析

    结果分析-loadrunner结果分析 by:授客 QQ:1033553122 百度网盘分享链接: 烦请 复制一下网址到浏览器中打开,输入密码提取 链接: http://pan.baidu.com/s ...

  4. TraceView工具的使用

    一.TraceView工具如何使用 TraceView有4种启动/关闭分析方式: (1) 第一种使用方法演示 1. 选择跟踪范围 在想要根据的代码片段之间使用以下两句代码 Debug.startMet ...

  5. Expo大作战(三十三)--expo sdk api之MapView(地图),MailComposer(磁力传感计),Lottie(动画)

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  6. 用PRODUCT_COPY_FILES拷贝文件夹

    拷贝文件PRODUCT_COPY_FILES += device/qcom/msm8909/media/media_profiles_8909.xml:system/etc/media_profile ...

  7. python第四十三天--第三模块考核

    面向对象: 概念:类,实例化,对象,实例 属性: 公有属性:在类中定义 成员属性:在方法中定义 私有属性:在方法中使用 __属性  定义 限制外部访问 方法: 普通方法 类方法: @classmeth ...

  8. MySql数据库基础笔记(一)

    一.表与库的概念 数据库管理数据,它是以什么样的形式组成的? 生活中的表---->表 table多行多列,传统的数据库都是这样的;声明了表头,一个表创建好了,剩下的就是往表中添加数据 多张表放在 ...

  9. Linux 小知识翻译 - 「分区」

    安装Linux的时候,需要对硬盘进行分区.那么「分区」到底是什么呢? 「分区」在日语中有区分,分割的意思.计算机术语中有时会说「对一个磁盘进行分区」,整个意思就是指定如何分割磁盘的意思. 「对磁盘进行 ...

  10. 第一条:了解Objective-C语言的起源

    第一条:了解Objective-C语言的起源 Objective-C使用的消息结构而非函数调用. Objective-C的重要工作都由"运行组件(runtime component)&quo ...