其实就是个大模拟。

首先,根据题意,小A和小B从任意一个城市开始走,无论\(X\)如何,其路径是一定唯一的。

显然对于两问都可以想出一个\(O(n^2)\)的暴力,即直接一步一步地向右走。

首先,我们当然需要知道A,B在每个城市的下一步如何走,记\(nexta(i),nextb(i)\)为A,B在\(i\)处时,下一步走到的城市编号。

考虑如何高效(复杂度小于等于\(O(nlogn)\))维护两个\(next\)。

显然不能直接维护每个城市与其后面的城市的差值,再好的数据结构也会到\(O(n^2)\)。

不妨考虑从后往前依次插入\(H_i\),然后动态维护\(H_i\sim H_n\)的有序集合。这样的话,在有序集合中,最小的差值一定要么是\(H_i\)与其前驱,要么就是与其后继的差值。次小的差值,就是\(H_i\)前驱、前驱的前驱、后继、后继的后继与\(H_i\)的差值的次小值。这个问题,平衡树解决之,预处理\(O(nlogn)\)。

下面考虑走\(k\)步的情况,当前步是A走还是B走与步数的奇偶性有关,因此我们还要分开讨论。

那么,我们不妨考虑以此为基础进行优化,比如优化到\(O(nlogn)\)。显然地,对于这样的问题,我们可以倍增预处理,\(O(logn)\)询问。

接下来考察我们需要什么信息,分别是\(i\)向后走\(k\)步的城市,A和B从\(i\)向后走\(k\)步的路程。

设\(f[0/1][i][j]\)为从\(i\)位置,0A,1B向后走\(2^j\)步的城市。

显然

\[f[0][i][0]=nexta(i)\\f[1][i][0]=nextb(i)
\]

由于,走\(2^0\)步是走奇数步,有转移

\[f[0][i][1]=f[1][f[0][i][0]][0]\\f[1][i][1]=f[0][f[1][i][0]][0]
\]

对于走\(2^j\)步,有

\[f[0][i][j]=f[0][f[0][i][j-1]][j-1]\\f[1][i][j]=f[1][f[1][i][j-1]][j-1]
\]

设\(da[0/1][i][j]\)表示从\(i\)位置,A向后走\(2^j\)步的路程,且现在(当前步)是0A,1B在开车,还没走时的A开的距离

显然

\[da[0][i][0]=dist(i,nexta(i))\\da[1][i][0]=0
\]

有转移

\[da[0][i][1]=da[0][i][0]+da[1][f[0][i][0]][0]\\da[1][i][1]=da[1][i][0]+da[0][f[1][i][0]][0]\\da[0][i][j]=da[0][i][j-1]+da[0][f[0][i][j-1]][j-1]\\da[1][i][j]=da[1][i][j-1]+da[1][f[1][i][j-1]][j-1]
\]

设\(db[0/1][i][j]\)表示从\(i\)位置,B向后走\(2^j\)步的路程,且现在是0A,1B在开车。

跟\(da\)差别不大,不再赘述。

预处理完成之后,我们开始考虑题述问题。

对于第一问,对给出的\(X_0\),我们枚举城市\(S_i\),倍增统计走\(X_0\)步的答案(当然超出\(N\)要特判),\(O(nlogn)\)解决之。

对于第二问,同样的,对于每一组\(S_i,X_i\),直接倍增统计即可,复杂度\(O(mlogn)\)。

总复杂度在\(O((n+m)logn)\)左右,完全可以通过本题。

注意,这道题的细节之数量足以让人去世。

代码未经重构,很丑。

参考代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<vector>
#define INF 0x7fffffff
#define PI acos(-1.0)
#define N 100010
#define MOD 2520
#define E 1e-12
#define ll long long
using namespace std;
inline ll read()
{
ll f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
set<int> h;
map<int,int> mp;
int t;
ll n,a[N],na[N],nb[N],f[2][N][21],da[2][N][21],db[2][N][21];
int main()
{
n=read();t=log2(n);
for(int i=1;i<=n;++i) a[i]=read();
a[0]=INF,a[n+1]=-INF;
h.insert(INF);
h.insert(-INF);
mp[-INF]=0,mp[INF]=n+1;
for(int i=n;i>=1;--i){
h.insert(a[i]);mp[a[i]]=i;
ll n1=((++h.find(a[i])!=h.end())?(*++h.find(a[i])):INF),n2=(((++(++h.find(a[i])))!=h.end())?(*++(++h.find(a[i]))):INF);
ll p1=((h.find(a[i])!=h.begin())?(*--h.find(a[i])):-INF),p2=((--h.find(a[i])!=h.end())?(*--(--h.find(a[i]))):-INF);
if(n1-a[i]>=a[i]-p1){
nb[i]=mp[p1];
na[i]=(n1-a[i]>=a[i]-p2)?mp[p2]:mp[n1];
}
else{
nb[i]=mp[n1];
na[i]=(n2-a[i]>=a[i]-p1)?mp[p1]:mp[n2];
}
f[0][i][0]=na[i];f[1][i][0]=nb[i];
da[0][i][0]=abs(a[i]-a[na[i]]);
db[1][i][0]=abs(a[i]-a[nb[i]]);
}
for(int j=1;j<=t;++j){
for(int i=1;i<=n;++i){
if(j==1){
f[0][i][1]=f[1][f[0][i][0]][0];
f[1][i][1]=f[0][f[1][i][0]][0];
da[0][i][1]=da[0][i][0]+da[1][f[0][i][0]][0];
da[1][i][1]=da[1][i][0]+da[0][f[1][i][0]][0];
db[0][i][1]=db[0][i][0]+db[1][f[0][i][0]][0];
db[1][i][1]=db[1][i][0]+db[0][f[1][i][0]][0];
}else{
f[0][i][j]=f[0][f[0][i][j-1]][j-1];
f[1][i][j]=f[1][f[1][i][j-1]][j-1];
da[0][i][j]=da[0][i][j-1]+da[0][f[0][i][j-1]][j-1];
da[1][i][j]=da[1][i][j-1]+da[1][f[1][i][j-1]][j-1];
db[0][i][j]=db[0][i][j-1]+db[0][f[0][i][j-1]][j-1];
db[1][i][j]=db[1][i][j-1]+db[1][f[1][i][j-1]][j-1];
}
}
}/
int x0=read(),s0=0;
double ans=1e14,nans=1e14;//task 1
for(int i=1;i<=n;++i){
int now=i;
ll resa=0,resb=0;
for(int j=t;j>=0;--j){
if(f[0][now][j]){
if(resa+resb+da[0][now][j]+db[0][now][j]>x0)
continue;
resa+=da[0][now][j];resb+=db[0][now][j];
now=f[0][now][j];
}
}
nans=(double)resa/(double)resb;
if(nans<ans){
ans=nans,s0=i;
}
else{
if(nans==ans&&a[s0]<a[i]) s0=i;
}
}
printf("%d\n",s0);
int m=read();//task 2
while(m--){
ll si=read(),xi=read();
ll resa=0,resb=0,now=si;
for(int j=t;j>=0;--j){
if(f[0][now][j]){
if(resa+resb+da[0][now][j]+db[0][now][j]>xi)
continue;
resa+=da[0][now][j];resb+=db[0][now][j];
now=f[0][now][j];
}
}
printf("%lld %lld\n",resa,resb);
}
return 0;
}

P1081 开车旅行[倍增](毒瘤题)的更多相关文章

  1. 洛谷 P1081 开车旅行 —— 倍增

    题目:https://www.luogu.org/problemnew/show/P1081 真是倍增好题! 预处理:f[i][j] 表示从 i 点开始走 2^j 次 AB (A,B各走一次)到达的点 ...

  2. 洛谷P1081 开车旅行(倍增)

    题意 题目链接 Sol 咕了一年的题解.. 并不算是很难,只是代码有点毒瘤 \(f[i][j]\)表示从\(i\)号节点出发走了\(2^j\)轮后总的距离 \(da[i][j]\)同理表示\(a\)的 ...

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

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

  4. 洛谷 P1081 开车旅行(70)

    P1081 开车旅行 题目描述 小AA 和小BB 决定利用假期外出旅行,他们将想去的城市从 11到 NN 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 ii的海 ...

  5. 2018.11.04 洛谷P1081 开车旅行(倍增)

    传送门 思路简单码量超凡? 感觉看完题大家应该都知道是倍增sbsbsb题了吧. 首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点. 然后利用刚刚预处理出的信息再预处理从每个点出发 ...

  6. 洛谷 P1081 开车旅行【双向链表+倍增】

    倍增数组的20和N写反了反复WAWAWA-- 注意到a和b在每个点上出发都会到一个指定的点,所以这样构成了两棵以n点为根的树 假设我们建出了这两棵树,对于第一问就可以枚举起点然后倍增的找出ab路径长度 ...

  7. [NOIP2012] 提高组 洛谷P1081 开车旅行

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

  8. P1081 开车旅行

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

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

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

随机推荐

  1. 2018-2019-2 20165315《网络对抗技术》Exp9 Web安全基础

    2018-2019-2 20165315<网络对抗技术>Exp9 Web安全基础 目录 一.实验内容 二.实验步骤 1.Webgoat前期准备 2.SQL注入攻击 Command Inje ...

  2. Lambda表达式和方法引用

    1 , 为什么用lambda表达式 将重复固定的代码写法简单化 2   ,lambda表达式的实质 对函数式接口的实现(一个接口中只有一个抽象方法的接口被称为函数式接口) package com.mo ...

  3. C/C++ static 关键字

    在 C/C++ 中,static 关键字使用恰当能够大大提高程序的模块化特性. static 在 C++ 类之中和在类之外的作用不一样,在C语言中的作用和在 C++ 类之外的作用相同,下面一一说明: ...

  4. Java学习:内部类的概念于分类

    内部类的概念于分类 如果一个事物的内部类包含另一个事物,那么这就是一个类内部包含另一个类.例如:身体和心脏的关系,又如:汽车和发动机的关系. 分类 成员内部类 局部内部类(包含匿名内部类) 成员内部类 ...

  5. golang ----并发 && 并行

    Go 语言的线程是并发机制,不是并行机制. 那么,什么是并发,什么是并行? 并发是不同的代码块交替执行,也就是交替可以做不同的事情. 并行是不同的代码块同时执行,也就是同时可以做不同的事情. 举个生活 ...

  6. 信安周报-第03周:DB系统表

    信安之路 第03周 前言 这周自主研究的任务如下: 任务附录的解释: 文件读写在通过数据库注入漏洞获取webshell的时候很有用 系统库和表存放了很多关键信息,在利用注入漏洞获取更多信息和权限的过程 ...

  7. 封装:WPF绘制曲线视图

    原文:封装:WPF绘制曲线视图 一.目的:绘制简单轻量级的曲线视图 二.实现: 1.动画加载曲线 2.点击图例显示隐藏对应曲线 3.绘制标准基准线 4.绘制蒙板显示标准区域 曲线图示例: 心电图示例: ...

  8. vs2015下编译免费开源的jpeg库,ijg的jpeg.lib

    vs2015下编译免费开源的jpeg库,ijg的jpeg.lib 1. 去Independent JPEG Group官网www.ijg.org下载jpegsrc,我下载的版本是jpegsrc9c.z ...

  9. Linux 脚本在线安装docker

    2019/11/28, CentOS 8, docker 19.03.5, docker-compose 1.25.0 摘要:CentOS8使用脚本安装docker,dnf安装rpm,安装docker ...

  10. Navicat 破解版(操作非常简单)

    Navicat 破解版(操作非常简单) 参考这位老哥的博客,之前试过好多个,只有这个是最简单有效的 https://blog.csdn.net/WYpersist/article/details/86 ...