Codeforces 1249E By Elevator or Stairs? 题解
这题其实和 NIKKEI 2019-2-D Shortest Path on a Line 差不多的啦,都是一种最短路的变形,把多个点和边关联了起来。
题面
你要从一楼到 \(n\) 楼去,每层楼可以选择坐电梯和走楼梯,第 \(i\) 和 \(i+1\) 层之间的楼梯花费 \(a_i\) 时间,而电梯花费 \(b_i\) 时间,而且进出电梯有个时间成本 \(c\)。
那么显然,从 \(x\) 楼到 \(y\) 楼走楼梯的花费是 \(\sum\limits_{i=min(x, y)}^{max(x, y) - 1} a_i\),坐电梯的花费是 \(c + \sum\limits_{i=min(x, y)}^{max(x, y) - 1} b_i\)(这里直接把 CF 上面的式子抄过来了)。
题解
首先有以下结论:
(1) 从底到顶的最短距离是单调递增的
因为整个上楼的操作是连续的,假如有一个从一楼到 \(p_2\) 楼的最短路比一楼到 \(p_1\) 楼的最短路要短(其中 \(p_1<p_2\)),那么就逆推回去(注意此处不是坐电梯或走楼梯下楼,是逆推),就变成了从 \(p_2\) 上减去一定的时间,显然此时一定会比 \(p_2\) 小。
(2) 到达每层楼的最短路径长度不需要从比它高的楼推出
结论 (1) 中为了证明单调递增,使用了从楼上推回楼下的做法,实际操作中并没有必要,因为由单调递增可知如果是从楼上再下来(不是逆推)必定比楼下上来时间长,因此结论得证。
由以上结论可以得到一个解法,即用线段树维护下面各层楼到这层楼坐电梯和走路的时间加上一楼到该层楼的时间,然后在每层楼选取一个最优的方案上来即可,注意储存坐电梯上来时的花费减去 \(c\),防止多段连续的电梯乘坐。
代码
#include<cstdio>
#include<algorithm>
#define ls pos<<1
#define rs (pos<<1)+1
#define MID (tree[pos].l+tree[pos].r)>>1
const int MAXN=2e5+5;
struct Tree{int l,r;long long val,lazy;};
int n,c;long long s[MAXN],e[MAXN];
struct SegTree
{
Tree tree[MAXN*4];
void BuildTree(int l,int r,int pos)
{
tree[pos].l=l;tree[pos].r=r;tree[pos].val=4e9+7;
if(l==r) return;
int mid=MID;
BuildTree(l,mid,ls);BuildTree(mid+1,r,rs);
}
void DownReload(int pos)
{
if(tree[pos].lazy)
{
tree[ls].lazy+=tree[pos].lazy;
tree[rs].lazy+=tree[pos].lazy;
tree[ls].val+=tree[pos].lazy;
tree[rs].val+=tree[pos].lazy;
tree[pos].lazy=0;
return;
}
}
void UpReload(int pos){tree[pos].val=std::min(tree[ls].val,tree[rs].val);}
void SegUpdate(int l,int r,long long delta,int pos)//ADD value
{
if(l<=tree[pos].l&&r>=tree[pos].r)
{
tree[pos].val+=delta;
tree[pos].lazy+=delta;
return;
}
DownReload(pos);
int mid=MID;
if(r<=mid) SegUpdate(l,r,delta,ls); else if(l>mid) SegUpdate(l,r,delta,rs); else {SegUpdate(l,mid,delta,ls);SegUpdate(mid+1,r,delta,rs);}
UpReload(pos);
}
void PtUpdate(int target,long long delta,int pos)//SET value
{
if(tree[pos].l==tree[pos].r)
{
tree[pos].val=delta;
return;
}
DownReload(pos);
int mid=MID;
if(target<=mid) PtUpdate(target,delta,ls); else PtUpdate(target,delta,rs);
UpReload(pos);
}
long long Query(int l,int r,int pos)
{
if(l==tree[pos].l&&r==tree[pos].r) return tree[pos].val;
DownReload(pos);
int mid=MID;
if(r<=mid) return Query(l,r,ls); else if(l>mid) return Query(l,r,rs); else return std::min(Query(l,mid,ls),Query(mid+1,r,rs));
}
};
SegTree elv,stair;
int main()
{
scanf("%d %d",&n,&c);
for(int i=2;i<=n;i++)
scanf("%lld",&s[i]);
for(int i=2;i<=n;i++)
scanf("%lld",&e[i]);
printf("0 ");
elv.BuildTree(1,n,1);
stair.BuildTree(1,n,1);
elv.PtUpdate(1,0,1);
stair.PtUpdate(1,0,1);
long long re,rstr,min;
for(int i=2;i<=n;i++)
{
elv.SegUpdate(1,i-1,e[i],1);
re=elv.Query(1,i-1,1)+c;
stair.SegUpdate(1,i-1,s[i],1);
rstr=stair.Query(1,i-1,1);
if(re<rstr)
{
elv.PtUpdate(i,re-c,1);
stair.PtUpdate(i,re,1);
printf("%lld ",re);
}
else
{
elv.PtUpdate(i,rstr,1);
stair.PtUpdate(i,rstr,1);
printf("%lld ",rstr);
}
}
return 0;
}
Codeforces 1249E By Elevator or Stairs? 题解的更多相关文章
- [题解]Mail.Ru Cup 2018 Round 1 - A. Elevator or Stairs?
[题目] A. Elevator or Stairs? [描述] Masha要从第x层楼去第y层楼找Egor,可以选择爬楼梯或者坐直升电梯.已知爬楼梯每层需要时间t1:坐直升电梯每层需要时间t2,直升 ...
- # Codeforces Round #529(Div.3)个人题解
Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Re ...
- Codeforces 547C/548E - Mike and Foam 题解
目录 Codeforces 547C/548E - Mike and Foam 题解 前置芝士 - 容斥原理 题意 想法(口胡) 做法 程序 感谢 Codeforces 547C/548E - Mik ...
- Codeforces Round #557 (Div. 1) 简要题解
Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...
- Codeforces Round #665 (Div. 2)A-C题解
A. Distance and Axis 题目:http://codeforces.com/contest/1401/problem/A 题解:对于n来说分两种情况,一是奇数,二则是偶数 ①奇数:对于 ...
- Codeforces Round #668 (Div. 2)A-C题解
A. Permutation Forgery 题目:http://codeforces.com/contest/1405/problem/A 题解:这道题初看有点吓人,一开始居然想到要用全排序,没错我 ...
- Codeforces Round #669 (Div. 2)A-C题解
A. Ahahahahahahahaha 题目:http://codeforces.com/contest/1407/problem/A 题解:最多进行n/2的操作次数,我们统计这n个数中1的个数,是 ...
- Codeforces GYM 100876 J - Buying roads 题解
Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...
- Codeforces 983C Elevator dp (看题解)
Elevator 怎么今天写啥题都不会写啊, 我是傻了吗.. 把电梯里面四个人的目标点当作状态, 然后暴力转移. #include<bits/stdc++.h> #define LL lo ...
随机推荐
- 【MySQL】安装及配置
" 目录 #. 概述 1. 什么是数据(Data) 2. 什么是数据库(DataBase, 简称DB) 3. 什么是数据库管理系统(DataBase Management System) 4 ...
- POJ 2142 The Balance(exgcd)
嗯... 题目链接:http://poj.org/problem?id=2142 AC代码: #include<cstdio> #include<iostream> using ...
- Could not transfer artifact org.springframework.boot:spring-boot-starter-parent:pom:2.1.9.RELEASE from/to 阿里云镜像地址
今天从 http://start.spring.io/ 下载的demo项目,导入eclipse后,pom文件一直报 parent包错,然后感觉就是自己maven镜像里面搜不到这个包, 所以改了 mav ...
- WLC-WLC升级(以2504为例)
1.WLC升级需要按照升级路径来操作,低版本到高版本的跨度太大,往往需要升级到中间版本,有时候还涉及到FUS. 2.我们升级,一般使用的笔记本上运行的TFTP/FTP server. 需要注意:笔记 ...
- java_1:为什么我一搞PHP的要转JAVA
为什么我一搞PHP的要高JAVA? 没什么!就他妈逼的看不惯搞JAVA那群逼鄙视PHPer的样!你会JAVA,稍微发功老子一样搞!
- SpringBoot学习笔记(二)——Springboot项目目录介绍
官网生成SpringBoot项目 使用官网(https://start.spring.io/)生成一个Maven构建的的SpringBoot项目,下载下来的文件是这个样子的. 导入到IDEA中 为了查 ...
- 洛谷 T8088 RQY的舞会
嗯... 题目链接:https://www.luogu.org/problem/T8088 这道题很好想,我想的是维护两个小根堆(当然可以用数组模拟) 然后从堆顶开始,如果两个元素的差小于1,则cnt ...
- 使用Shiro实现认证和授权(基于SpringBoot)
Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案.下面是在SpringBoot中使用Shiro进行认证和授权 ...
- kubernetes从入门到放弃(二)
kubernetes对象之pod 1.pod的认识 Pod直译是豆荚,可以把容器想像成豆荚里的豆子,把一个或多个关系紧密的豆子包在一起就是豆荚(一个Pod).在Kubernetes中我们不会直接操作容 ...
- linux 从一台机器复制文件到另一台linux机器上去
1.功能说明scp就是security copy,用于将文件或者目录从一个Linux系统拷贝到另一个Linux系统下.scp传输数据用的是SSH协议,保证了数据传输的安全,其格式如下:scp 远程用户 ...