洛谷 P1081 开车旅行 —— 倍增
题目:https://www.luogu.org/problemnew/show/P1081
真是倍增好题!
预处理:f[i][j] 表示从 i 点开始走 2^j 次 AB (A,B各走一次)到达的点;
sta[i][j] 表示从 i 点开始走 2^j 次 AB 后 A 走过的总路程;stb 为 B 的;
首先要找到 2^0 位置上的,也就是右边最近的和次近的点;
先把点按海拔排序,那么最近点和次近点一定在 i-2 , i-1 , i+1 , i+2 这四个位置;
又不能找到 i 之前的点,所以需要支持查询周边四个值并且可以删除的数据结构,可以用双向链表(用结构体存一个 l 和 r 即可);
然后倍增预处理出 f , sta , stb 数组,倍增查询即可;
倍增预处理时把 f 写成 sta,stb 改了好久囧...还是不能对应照抄上面一行啊...
还有一定注意预处理的倍增要外层 j 内层 i !
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=1e5+,inf=1e9;
int n,m,f[maxn][],h[maxn],p[maxn],na[maxn],nb[maxn];
ll sta[maxn][],stb[maxn][];
struct N{int id,h,l,r;}d[maxn];
bool cmp(N x,N y){return (x.h==y.h)?x.id<y.id:x.h<y.h;}
bool lf(int x,int l,int r)//是否选 l
{
if(!l)return ;
if(!r)return ;
return d[x].h-d[l].h<=d[r].h-d[x].h;//=
}
void init()
{
for(int i=;i<=n;i++)
{
f[i][]=nb[na[i]];
sta[i][]=abs(h[i]-h[na[i]]);
stb[i][]=abs(h[f[i][]]-h[na[i]]);
}
for(int j=;j<;j++)//外j内i
for(int i=;i<=n;i++)
{
f[i][j]=f[f[i][j-]][j-];
// sta[i][j]=sta[i][j-1]+sta[sta[i][j-1]][j-1];
// stb[i][j]=stb[i][j-1]+stb[stb[i][j-1]][j-1];
sta[i][j]=sta[i][j-]+sta[f[i][j-]][j-];//f!囧
stb[i][j]=stb[i][j-]+stb[f[i][j-]][j-];
}
}
void get(int p,ll x,ll &a,ll &b)//ll
{
a=; b=; ll d=;
for(int i=;i>=;i--)
if(f[p][i]&&d+sta[p][i]+stb[p][i]<=x)
{
a+=sta[p][i]; b+=stb[p][i];
d+=sta[p][i]+stb[p][i]; p=f[p][i];
}
if(na[p]&&d+sta[p][]<=x)a+=sta[p][];//A再走一步
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&h[i]),d[i].h=h[i],d[i].id=i;
sort(d+,d+n+,cmp);
for(int i=;i<=n;i++)p[d[i].id]=i,d[i].l=i-,d[i].r=i+;
d[].l=d[n].r=;
for(int i=;i<=n;i++)
{
int j=p[i],l=d[j].l,r=d[j].r;
if(lf(j,l,r))nb[i]=d[l].id,na[i]=(lf(j,d[l].l,r)?d[d[l].l].id:d[r].id);//id
else nb[i]=d[r].id,na[i]=(lf(j,l,d[r].r)?d[l].id:d[d[r].r].id);
if(l)d[l].r=r;
if(r)d[r].l=l;//删除j
}
init();
int ans; ll x; double mn=inf;
scanf("%lld%d",&x,&m);
ll a,b;
for(int i=;i<=n;i++)
{
get(i,x,a,b);
if(!b)continue;
double k=1.0*a/b;
if(mn>k)mn=k,ans=i;
else if(mn==k&&h[ans]<h[i])ans=i;
}
printf("%d\n",ans);
for(int i=,x,p;i<=m;i++)
{
scanf("%d%lld",&p,&x);
get(p,x,a,b);
printf("%lld %lld\n",a,b);
}
return ;
}
洛谷 P1081 开车旅行 —— 倍增的更多相关文章
- 洛谷P1081 开车旅行(倍增)
题意 题目链接 Sol 咕了一年的题解.. 并不算是很难,只是代码有点毒瘤 \(f[i][j]\)表示从\(i\)号节点出发走了\(2^j\)轮后总的距离 \(da[i][j]\)同理表示\(a\)的 ...
- 洛谷 P1081 开车旅行(70)
P1081 开车旅行 题目描述 小AA 和小BB 决定利用假期外出旅行,他们将想去的城市从 11到 NN 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 ii的海 ...
- 2018.11.04 洛谷P1081 开车旅行(倍增)
传送门 思路简单码量超凡? 感觉看完题大家应该都知道是倍增sbsbsb题了吧. 首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点. 然后利用刚刚预处理出的信息再预处理从每个点出发 ...
- 洛谷 P1081 开车旅行【双向链表+倍增】
倍增数组的20和N写反了反复WAWAWA-- 注意到a和b在每个点上出发都会到一个指定的点,所以这样构成了两棵以n点为根的树 假设我们建出了这两棵树,对于第一问就可以枚举起点然后倍增的找出ab路径长度 ...
- [NOIP2012] 提高组 洛谷P1081 开车旅行
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- NOIP 2012 洛谷P1081 开车旅行
Description: 就是两个人开车,只能向东开.向东有n个城市,城市之间的距离为他们的高度差.A,B轮流开车,A喜欢到次近的城市,B喜欢到最近的城市.如果车子开到底了或者车子开的路程已经超过了限 ...
- 洛谷P1081 开车旅行
题目 双向链表+倍增+模拟. \(70pts\): 说白了此题的暴力就是细节较多的模拟题. 我们设离\(i\)城市最近的点的位置为\(B[i]\),第二近的位置为\(A[i]\).设\(A\)或\(B ...
- 洛谷P1081——开车旅行
传送门:QAQQAQ 题意注意点: 1.是从前往后走,不能回头 2.小A小B轮流开,先小A开,而小A是到第二近的点(这点调试的时候查了好久) 3.若绝对值差相同海拔低的更近,而第一个询问若比值相同是海 ...
- 洛谷P1081 开车旅行70分
https://www.luogu.org/problem/show?pid=1081 太遗憾了明明写出来了,却把最小值初始值弄小了,从第二个点开始就不可能对了.70分! #include<io ...
随机推荐
- 开发者自建IM服务器必须要解决的几个问题!
有很多朋友的项目需要用到即时通讯,几年前鄙人的项目也是如此,当年没有选择,只能自建了IM服务器,几年下来跨了不少的坑,想想都甚是后怕.总结此文为后来还想自建IM的朋友提个醒,或许能找到更好的解决之路. ...
- 基于证书的MS SQL2005数据库镜像搭建
一.准备工作: 3台服务器同版本,硬盘分区大小相同,安装相同版本数据库软件. host中分别标注3台服务器IP和主机名称. 主体服务器上创建数据库,并进行完整备份数据库和数据库事务. 拷贝备份文件给镜 ...
- THREE.js代码备份——webgl - geometry - dynamic(模拟海浪,通过时间(毫秒)来控制平面点的运动模拟海浪,鼠标控制写在另外的js中)
HTML: <!DOCTYPE html> <html lang="en"> <head> <title>three.js webg ...
- (转)Arcgis for javascript实现百度地图ABCD marker的效果
概述: 在我的博客中,有一篇相关的文章,这段时间,有很多人问我求源码,只是时间过去已长,源代码已找不到,乘着这个9.3放假,又重新实现了下,并相关代码做了优化,在此贴出来,方便大家使用. 相关文章地址 ...
- pycharm之gitignore设置
首先检查pycharm是否安装了ignore插件 项目目录如图: 选中项目automationTest名称,右击-->New-->查看是否有ignore file选项,如果有表示Pycah ...
- 用C#在Visual Studio写Javascript单元测试(Firefox内核)
引用nuget包: 注意:Geckofx45 nuget包必须是最后引用,否则初始化会出错 编写JsRunner using Gecko; using System; using System.Col ...
- Async/await语法糖实现(Generator)
// generator也是一种迭代器(Iterator) 有next方法,并返回一个对象{value:...,done:...} function run(generatorFunction) { ...
- 模板中tempname与class区别
前言 在分析traits编程之前, 我们需要对模板参数类型tempname和class有一定的了解, 要明白他们在哪些方面不同, 哪些方面相同, 这样才能对体会到traits编程的核心. 如果你已经明 ...
- java面试题(转)
1.面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些 ...
- 00.不规则json序列化使用eval、demjson
有下面一段字符串 import json str0 = '[{"name":"白云大道营业厅","siteaddr":"x...& ...