这题其实和 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? 题解的更多相关文章

  1. [题解]Mail.Ru Cup 2018 Round 1 - A. Elevator or Stairs?

    [题目] A. Elevator or Stairs? [描述] Masha要从第x层楼去第y层楼找Egor,可以选择爬楼梯或者坐直升电梯.已知爬楼梯每层需要时间t1:坐直升电梯每层需要时间t2,直升 ...

  2. # Codeforces Round #529(Div.3)个人题解

    Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Re ...

  3. Codeforces 547C/548E - Mike and Foam 题解

    目录 Codeforces 547C/548E - Mike and Foam 题解 前置芝士 - 容斥原理 题意 想法(口胡) 做法 程序 感谢 Codeforces 547C/548E - Mik ...

  4. Codeforces Round #557 (Div. 1) 简要题解

    Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...

  5. Codeforces Round #665 (Div. 2)A-C题解

    A. Distance and Axis 题目:http://codeforces.com/contest/1401/problem/A 题解:对于n来说分两种情况,一是奇数,二则是偶数 ①奇数:对于 ...

  6. Codeforces Round #668 (Div. 2)A-C题解

    A. Permutation Forgery 题目:http://codeforces.com/contest/1405/problem/A 题解:这道题初看有点吓人,一开始居然想到要用全排序,没错我 ...

  7. Codeforces Round #669 (Div. 2)A-C题解

    A. Ahahahahahahahaha 题目:http://codeforces.com/contest/1407/problem/A 题解:最多进行n/2的操作次数,我们统计这n个数中1的个数,是 ...

  8. Codeforces GYM 100876 J - Buying roads 题解

    Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...

  9. Codeforces 983C Elevator dp (看题解)

    Elevator 怎么今天写啥题都不会写啊, 我是傻了吗.. 把电梯里面四个人的目标点当作状态, 然后暴力转移. #include<bits/stdc++.h> #define LL lo ...

随机推荐

  1. CentOS 7----Apache基于域名的虚拟主机配置

    配置/etc/hosts文件,192.168.1.209 对应的域名如下: 192.168.1.209 www.name1.com 编辑每个域名的配置文件: <VirtualHost 192.1 ...

  2. ZOJ 1002 Fire Net(dfs)

    嗯... 题目链接:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364501 这道题是想出来则是一道很简单的dfs: 将一 ...

  3. Java连载81-枚举类型,生成五个不重复的随机数,集合简介

    一.枚举类型 1.枚举类型的格式就是enum+枚举类型的名称,可见下面的例子. package com.bjpowernode.java_learning; ​ public class D81_1_ ...

  4. VBA 学习笔记 - 日期

    date() 返回当前的系统日期 返回格式为 YYYY/MM/DD CDate() 学习资料:https://www.yiibai.com/vba/vba_cdate_function.html 将有 ...

  5. web渗透(转)

    某天比较无聊,听一个朋友推荐httpscan这款工具,于是就下载下来试试. 首先对某学校网段开始进行测试. 1   python httpscan.py **.**.**.0/24 测试时发现有个比较 ...

  6. .NET中的字符串(2):你真的了解.NET中的String吗?

    概述 String在任何语言中,都有它的特殊性,在.NET中也是如此.它属于基本数据类型,也是基本数据类型中唯一的引用类型.字符串可以声明为常量,但是它却放在了堆中.希望通过本文能够使大家对.NET中 ...

  7. 使用命令将单个java文件打包为jar

    思路:先将java文件编译为class文件,然后再打包为jar 参考博文:https://www.cnblogs.com/sxdcgaq8080/p/8126770.html http://www.m ...

  8. (0)Lora及LoraWAN

    Lora和LoraWAN的区别 LoRa经常被误用来描述整个LPWAN通信系统,其实Lora是Semtech拥有的专有调制格式. SX1272和SX1276 LoRa芯片使用称为chirp扩频(CSS ...

  9. 关于Java大整数是否是素数

    题目描述 请编写程序,从键盘输入两个整数m,n,找出等于或大于m的前n个素数. 输入格式: 第一个整数为m,第二个整数为n:中间使用空格隔开.例如: 103 3 输出格式: 从小到大输出找到的等于或大 ...

  10. leetCode练题——14. Longest Common Prefix

    1.题目 14. Longest Common Prefix   Write a function to find the longest common prefix string amongst a ...