洛谷 P3994 高速公路(斜率优化)
题意:给出一棵树,\(1\) 号点为根,边上有边权。
每个点有两个参数 \(p_i,q_i\)
如果你想从 \(i\) 号点到与其距离为 \(d\) 的 \(j\) 号点,那么你需花费 \(d \times p_i+q_i\)。
对于每个 \(i \in [2,n]\),求出:假设你站在 \(i\) 号点,到达 \(1\) 号点的最小花费。
\(1 \leq n \leq 10^6\)
树上斜率优化
dfs 求出 \(i\) 到根节点的路径长度为 \(d_i\)。
朴素的 \(dp\) 非常容易。设 \(dp_i\) 表示到达 \(i\) 号点的最小花费。那么显然
\]
假设 \(j\) 在 \(k\) 的下方,那么 \(j\) 比 \(k\) 更优当且仅当:
\]
\]
\]
\]
开个队列维护 \(i\) 的祖先的点组成的下凸包,然后在队列里二分斜率就可以了。
/*
Contest: -
Problem: P3994
Author: tzc_wk
Time: 2020.5.29
*/
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define giveup(...) return printf(__VA_ARGS__),0;
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define mask(a) (1ll<<(a))
#define maskx(a,x) ((a)<<(x))
#define _bit(a,x) (((a)>>(x))&1)
#define _sz(a) ((int)(a).size())
#define filei(a) freopen(a,"r",stdin);
#define fileo(a) freopen(a,"w",stdout);
#define fileio(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define put(x) putchar(x)
#define eoln put('\n')
#define space put(' ')
#define y1 y1010101010101
#define y0 y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
int x=0,neg=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') neg=-1;
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*neg;
}
inline int qpow(int x,int e,int _MOD){
int ans=1;
while(e){
if(e&1) ans=ans*x%_MOD;
x=x*x%_MOD;
e>>=1;
}
return ans;
}
int n=read();
vector<pii> g[1000005];
int p[1000005],q[1000005],dep[1000005],dp[1000005];
int dq[1000005],hd=1,tl=0;
inline double sl(int j,int k){
return 1.0*(dp[k]-dp[j])/(dep[k]-dep[j]);
}
inline int bsearch(double slo){
if(hd==tl) return dq[hd];
int l=hd,r=tl-1,ans=tl;
while(l<=r){
int mid=(l+r)>>1;
if(sl(dq[mid],dq[mid+1])>=slo) ans=mid,r=mid-1;
else l=mid+1;
}
return dq[ans];
}
inline void dfs(int x){
int y=bsearch(p[x]);
int curhd=hd,curtl=tl;
dp[x]=dp[y]+(dep[x]-dep[y])*p[x]+q[x];
while(hd<tl&&sl(dq[tl],dq[tl-1])>sl(dq[tl],x)) tl--;
int curq=dq[++tl];
dq[tl]=x;
foreach(it,g[x]){
int z=it->first,s=it->second;
dep[z]=dep[x]+s;
dfs(z);
}
hd=curhd,dq[tl]=curq,tl=curtl;
}
signed main(){
fz(i,2,n){
int f=read(),s=read();
p[i]=read(),q[i]=read();
g[f].push_back({i,s});
}
dfs(1);
fz(i,2,n) cout<<dp[i]<<endl;
return 0;
}
洛谷 P3994 高速公路(斜率优化)的更多相关文章
- 洛谷 P3994 高速公路
https://www.luogu.org/problemnew/show/P3994 设dp[i] 表示第i个城市到根节点的最小花费 dp[i]=min{ (dis[i]-dis[j])*P[i]+ ...
- 【洛谷p3994】Highway 二分+斜率优化DP
题目大意:给你一颗$n$个点的有根树,相邻两个点之间有距离,我们可以从$x$乘车到$x$的祖先,费用为$dis\times P[x]+Q[x]$,问你除根以外每个点到根的最小花费. 数据范围:$n≤1 ...
- 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)
有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
- Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化
https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...
- 洛谷P2221 高速公路【线段树】
题目:https://www.luogu.org/problemnew/show/P2221 题意:有n个节点排成一条链,相邻节点之间有一条路. C u v val表示从u到v的路径上的每条边权值都加 ...
- 斜率优化DP学习笔记
先摆上学习的文章: orzzz:斜率优化dp学习 Accept:斜率优化DP 感谢dalao们的讲解,还是十分清晰的 斜率优化$DP$的本质是,通过转移的一些性质,避免枚举地得到最优转移 经典题:HD ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷 P5663 加工零件
题目传送门 解题思路: 最暴力的做法: bfs模拟,每次将一个阶段的所有点拿出来,将其所有直连的点都放进队列,知道本阶段结束,最后看1号点会不会在最后一个阶段被放入队列.(洛谷数据40分) 优化了一下 ...
随机推荐
- C++控制台应用程序一闪而过的解决方法
Visual Studio 2017 C++控制台应用程序, 如果编译时发现黑框一闪而过,请按以下步骤操作: 右键project → 属性 → 链接器 → 系统 → 子系统,在下拉菜单中改为控制台.
- Promise.resolve(x)中x有几种情况
ps:下面参数说的是Promise.resolve(x)中的x 一共四种情况: 1.如果参数是Promise实例本身,则抛出错误 2.如果参数是一个promise对象,则then函数的执行取决于这个参 ...
- SharkCTF2021 easy_phpserialize题记
***先说教训: (1)不要看到正则就走不动路:有些正则不一定能绕. (2)__wakeup()漏洞在php5.6以上就被修复了: 本地复现各种题目时要注意环境. -------- 扫描,得到inde ...
- Windows10使用技巧
Windows10配置技巧 新机配置 "我的电脑"图标设置 在桌面右击鼠标=>个性化=>点击左侧"主题"=>点击相关的设置中的"桌面 ...
- UltraSoft - Alpha - Scrum Meeting 1
Date: Apr 06th, 2020. 会议内容为讨论功能规格书和技术规格书的撰写. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM.后端 进行Djan ...
- freemarker自定义指令
最近项目中使用了spring boot搭建项目,使用spring security管理项目中的权限,使用freemarker作为视图层.为了将权限控制到按钮上,因此考虑直接使用spring secur ...
- 检查是否是BST 牛客网 程序员面试金典 C++ java Python
检查是否是BST 牛客网 程序员面试金典 C++ java Python 题目描述 请实现一个函数,检查一棵二叉树是否为二叉查找树. 给定树的根结点指针TreeNode* root,请返回一个boo ...
- 20191310Lee_yellow缓冲区溢出实验
缓冲区溢出实验 1.什么是缓冲区溢出 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据 ...
- VNC服务器的搭建(带图形化支持)
环境:centos7.6最小化安装 图形化支持 如果希望安装简单的图形支持的话,仅包含gnome的最最最最基础的包的话可以使用以下命令 yum groups install "X Windo ...
- Mac sourceTree每次都输入密码
打开终端 依次输入以下三条命令 curl http://github-media-downloads.s3.amazonaws.com/osx/git-credential-osxkeychain - ...