【洛谷p3994】Highway 二分+斜率优化DP
题目大意:给你一颗$n$个点的有根树,相邻两个点之间有距离,我们可以从$x$乘车到$x$的祖先,费用为$dis\times P[x]+Q[x]$,问你除根以外每个点到根的最小花费。
数据范围:$n≤10^6$。
此题我们显然$dp$,列出方程为$f[x]=min\{f[y]+dis(x,y)\times P[x]+Q[x]\}$,其中$y$为$x$的祖先。
不难看出可能是一个斜率优化的式子,我们往下推推
设$i$是$j$的祖先,且从$i$出转移比从$j$处转移劣,不难列出:
$f[i]+dis(i,x)P[x]+Q[x]>f[j]+dis(j,x)P[x]+Q[x]$
化简化简,令$D_i$表示从根到$i$的距离,继续移项化简
$f[i]-f[j]>P[x]((D_x-D_j)-(D_x-D_i))$
$f[i]-f[j]>P[x](D_i-D_j)$
$\dfrac{f[i]-f[j]}{D_i-D_j}<P[x]$(注意大于符号变成小于,因为$D_i<D_j$,重要!,我被坑了)
考虑到$P$随着点深度递增,于是就可以快乐斜率优化了。
不过这题需要在树上转移,当遍历完一个子树后,我们要把单调队列恢复,恢复操作显然可以用可持久化线段树来搞。
其实不用这么复杂,考虑到只存在移动队头,移动队尾&在队尾加一个数的操作,我们只需要记录下以前的队头/尾的情况,还有被覆盖的数原先是啥,就可以在常数时间内恢复回去。
然而这么做的话无法保证移动队头尾的次数是线性的(我们搞一个链+链底菊花树),所以在找队头和队尾时,需要用二分。
于是时间复杂度就变成$O(n\log\ n)$了,二分的常数很小,问题不大。
(我比较懒写了暴力移动的,二分的话自己脑补吧qwq)
#include<bits/stdc++.h>
#define M 1000005
#define L long long
using namespace std; struct edge{L u,v,next;}e[M]={}; L head[M]={},use=;
void add(L x,L y,L z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
L n,f[M]={},P[M]={},Q[M]={},dis[M]={},q[M]={},h=,t=; double slope(L i,L j){return .*(f[i]-f[j])/(dis[i]-dis[j]);} void dfs(L x,L D){
L H=h,T=t;
while(h<t&&P[x]>slope(q[h],q[h+])) h++;
f[x]=f[q[h]]+((dis[x]=D)-dis[q[h]])*P[x]+Q[x];
while(h<t&&slope(q[t-],q[t])>slope(q[t],x)) t--;
L lastT=q[++t]; q[t]=x;
for(L i=head[x];i;i=e[i].next) dfs(e[i].u,D+e[i].v);
q[t]=lastT; h=H; t=T;
} main(){
scanf("%lld",&n);
for(L i=;i<=n;i++){
L fa,dis; scanf("%lld%lld%lld%lld",&fa,&dis,P+i,Q+i);
add(fa,i,dis);
}
q[t=]=; for(L i=head[];i;i=e[i].next) dfs(e[i].u,e[i].v);
for(L i=;i<=n;i++) printf("%lld\n",f[i]);
}
【洛谷p3994】Highway 二分+斜率优化DP的更多相关文章
- 洛谷 P4072 [SDOI2016]征途 斜率优化DP
洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...
- 洛谷 P3994 高速公路(斜率优化)
题目链接 题意:给出一棵树,\(1\) 号点为根,边上有边权. 每个点有两个参数 \(p_i,q_i\) 如果你想从 \(i\) 号点到与其距离为 \(d\) 的 \(j\) 号点,那么你需花费 \( ...
- 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)
有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...
- UOJ#7 NOI2014 购票 点分治+凸包二分 斜率优化DP
[NOI2014]购票 链接:http://uoj.ac/problem/7 因为太麻烦了,而且暴露了我很多学习不扎实的问题,所以记录一下具体做法. 主要算法:点分治+凸包优化斜率DP. 因为$q_i ...
- Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP
E. Product Sum Blake is the boss of Kris, however, this doesn't spoil their friendship. They often ...
- SCUT - 365 - 鹏哥的数字集合 - wqs二分 - 斜率优化dp
https://scut.online/p/365 https://www.luogu.org/problemnew/solution/P2365 写这篇的时候还不是很明白,看一下这个东西. http ...
- 洛谷P2365 任务安排(斜率优化dp)
传送门 思路: 最朴素的dp式子很好考虑:设\(dp(i,j)\)表示前\(i\)个任务,共\(j\)批的最小代价. 那么转移方程就有: \[ dp(i,j)=min\{dp(k,j-1)+(sumT ...
- 洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP
做的第一道斜率优化\(DP\)QwQ 原题链接1/原题链接2 首先考虑\(O(n^2)\)的做法:设\(f[i]\)表示在\(i\)处建仓库的最小费用,则有转移方程: \(f[i]=min\{f[j] ...
- 2018.08.28 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化dp)
传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二 ...
随机推荐
- fastjson解析List对象
List<String[]> body = JSON.parseObject(msg.getBody().toString(), new TypeToken<List<Stri ...
- 2018.10.15 NOIP训练 hyc的等比数列(数论+枚举)
传送门 一道不错的枚举题. 显然桶排序之后瞎枚举一波. 考虑枚举首项和末项,假设首项除去一个最大的平方因子得到的结果为xxx. 那么末项一定等于xxx乘上一个平方数. 于是我们枚举首项,算出xxx然后 ...
- web页面中a标签下载文件包含中文下载失败的解决
之前用到的文件下载,文件名都是时间戳的形式或者英文名.下载没有问题.后来附件有中文后写在页面是下面效果,点击下载,下载失败. 对应链接拿出来.是如下效果 之前用了各种其他办法都不理想,比如转义什么的. ...
- C语言学生管理系统源码分享
大家好 我就是如假包换的...陈玲 自从运营了C语言程序设计微信公众号 很多粉丝都给我备注 ...奇葩 实在是不敢当 也被人开始叫玲玲姐 我知道 很多人都想看我出境 我本人也有 年多的舞台演讲训练 实 ...
- 使用yum命令报错File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:
背景: yum包的管理是使用python写的,有对应的python版本 遇到的问题报错如下: File "/usr/bin/yum", line 30 except K ...
- Python 正斜杠/与反斜杠\
首先,"/"左倾斜是正斜杠,"\"右倾斜是反斜杠,可以记为:除号是正斜杠一般来说对于目录分隔符,Unix和Web用正斜杠/,Windows用反斜杠,但是现在Wi ...
- WriteableBitmap(三) 扩展
backbuffer使用您在创建WriteableBitmap时指定的像素格式,还有一个BackBufferStride属性,您可以使用它来创建一个合适的存储映射函数. 添加一些方法来设置和获取特定情 ...
- shell 脚本 计算 1加到100 的和
#!/bin/bash # i=0 n=1 //定义循环变量 while [ $n -lt 101 ];do //定义循环条件 n < 101 i=$(( $i + $n )) //累加 n=$ ...
- Python学习-36.Python中的字典解释
具体同列表解释,也是使用if来进行过滤 例子,生成一个新的字典,并且是原来字典的键值交换. mydict={'Tom':18,'Mary':20} print({value:key for key,v ...
- web api 多版本控制重要的两个类
1.版本路径替换 public class ReplaceVersionWithExactValueInPath : IDocumentFilter { public void ...