[Noi2014]购票 斜率优化DP+可持久化凸包
貌似网上大部分题解都是CDQ分治+点分治然后再斜率优化DP,我貌似并没有用这个方法。
这一题跟这题有点像,只不过多了一个l的限制
如果说直接跑斜率优化DP,存储整个序列的话,显然是不行的,如图所示(图鸣谢某巨佬)

所以我们需要种一棵线段树,每个线段树内存储一个存当前区间凸包的单调栈,弹出插入操作跟刚刚说的那题一样。
查询的话就查询下整个区间中所有凸包上的最大值就可以了。
时间复杂度:$O(n\log^2\ n)$。写起来并不算很困难。
#include<bits/stdc++.h>
#define M 200005
#define L long long
#define INF (1LL<<62)
using namespace std; struct edge{int u,v,next;}e[M]={}; int head[M]={},use=;
void add(int x,int y,int z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
L D[M]={},P[M]={},Q[M]={},F[M]={},n,t,up[M]={};
double slope(int i,int j){return .*(F[i]-F[j])/(D[i]-D[j]);}
L getans(int x,int y){if(y==) return INF; return F[y]+(D[x]-D[y])*P[x]+Q[x];} int f[M][]={},dep[M]={};
int jump(int x,L dis){
for(int i=;~i;i--)
if(D[x]-D[f[x][i]]<=dis){
dis-=D[x]-D[f[x][i]];
x=f[x][i];
}
return max(,dep[x]);
} struct tb{
int *q,l,r;
tb(){l=; r=; q=NULL;}
tb(int len){
q=new int[len+];
memset(q,,sizeof(int )*(len+));
l=; r=;
}
int add(int x){
int ll=l,rr=r-;
if(l<r){
while(ll<rr){
int mid=(ll+rr)>>;
if(slope(q[mid],q[mid+])>slope(q[mid+],x)) rr=mid;
else ll=mid+;
}
if(slope(q[ll],q[ll+])<slope(q[ll+],x)) ll++;
r=ll;
}
int res=q[++r]; q[r]=x;
return res;
}
L getans(int x){
int ll=l,rr=r-;
if(l>=r) return q[l];
while(ll<rr){
int mid=(ll+rr+)>>;
if(slope(q[mid],q[mid+])<P[x]) ll=mid;
else rr=mid-;
}
if(slope(q[ll],q[ll+])<P[x])
return q[ll+];
return q[ll];
}
}; struct node{int l,r;tb a;}a[M*];
void build(int x,int l,int r){
a[x].l=l; a[x].r=r;
a[x].a=tb(r-l+);
if(l==r) return; int mid=(l+r)>>;
build(x<<,l,mid); build(x<<|,mid+,r);
}
void updata(int x,int k,int id,int lastL[],int lastR[],int lastT[]){
lastL[]=a[x].a.l; lastR[]=a[x].a.r;
lastT[]=a[x].a.add(id);
if(a[x].l==a[x].r) return; int mid=(a[x].l+a[x].r)>>;
if(k<=mid) updata(x<<,k,id,lastL+,lastR+,lastT+);
else updata(x<<|,k,id,lastL+,lastR+,lastT+);
}
void reset(int x,int k,int lastL[],int lastR[],int lastT[]){
a[x].a.q[a[x].a.r]=lastT[];
a[x].a.l=lastL[]; a[x].a.r=lastR[];
if(a[x].l==a[x].r) return; int mid=(a[x].l+a[x].r)>>;
if(k<=mid) reset(x<<,k,lastL+,lastR+,lastT+);
else reset(x<<|,k,lastL+,lastR+,lastT+);
}
L query(int x,int l,int r,int k){
if(l<=a[x].l&&a[x].r<=r)
return getans(k,a[x].a.getans(k));
L mid=(a[x].l+a[x].r)>>,minn=INF;
if(l<=mid) minn=min(minn,query(x<<,l,r,k));
if(mid<r) minn=min(minn,query(x<<|,l,r,k));
return minn;
} void dfs(int x,int fa,L Dis){
f[x][]=fa; dep[x]=dep[fa]+; D[x]=Dis;
for(int i=;i<;i++) f[x][i]=f[f[x][i-]][i-];
int y=jump(x,up[x]);
F[x]=query(,y,dep[x],x);
int lastL[]={},lastR[]={},lastT[]={};
updata(,dep[x],x,lastL,lastR,lastT);
for(int i=head[x];i;i=e[i].next) dfs(e[i].u,x,Dis+e[i].v);
reset(,dep[x],lastL,lastR,lastT);
}
int main(){
scanf("%d%d",&n,&t);
for(int i=;i<=n;i++){
L fa,dis; scanf("%lld%lld%lld%lld%lld",&fa,&dis,P+i,Q+i,up+i);
add(fa,i,dis);
}
build(,,n);
int hh[]; updata(,,,hh,hh,hh);
dep[]=; D[]=-INF;
for(int i=head[];i;i=e[i].next) dfs(e[i].u,,e[i].v);
for(int i=;i<=n;i++) printf("%lld\n",F[i]);
}
[Noi2014]购票 斜率优化DP+可持久化凸包的更多相关文章
- 【bzoj3672】[Noi2014]购票 斜率优化dp+CDQ分治+树的点分治
题目描述 给出一棵以1为根的带边权有根树,对于每个根节点以外的点$v$,如果它与其某个祖先$a$的距离$d$不超过$l_v$,则可以花费$p_vd+q_v$的代价从$v$到$a$.问从每个点到1花费 ...
- [NOI2014]购票 --- 斜率优化 + 树形DP + 数据结构
[NOI2014]购票 题目描述 今年夏天,NOI在SZ市迎来了她30周岁的生日. 来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每 ...
- [NOI2014]购票(斜率优化+线段树)
题目描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的父亲用道路连接 ...
- [BZOJ3672][Noi2014]购票 斜率优化+点分治+cdq分治
3672: [Noi2014]购票 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1749 Solved: 885[Submit][Status][ ...
- [NOI2014]购票——斜率优化+树链剖分+线段树
建议到UOJ上去交 题解 一眼\(DP\),先把转移方程写出来 设\(dp[i]\)为从点\(i\)出发到点\(1\)的最小费用,那么存在转移 \[f[i]=min\{f[j]+(d[i]-d[j]) ...
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...
- 斜率优化DP学习笔记
先摆上学习的文章: orzzz:斜率优化dp学习 Accept:斜率优化DP 感谢dalao们的讲解,还是十分清晰的 斜率优化$DP$的本质是,通过转移的一些性质,避免枚举地得到最优转移 经典题:HD ...
- 【学习笔记】动态规划—斜率优化DP(超详细)
[学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...
- HDU3507 Print Article(斜率优化dp)
前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...
随机推荐
- 面向对象先修:Java入门
学习总结 在C语言和数据结构的基础上,在上暑期的面向对象Java先修课程时,熟悉语言的速度明显加快了很多.Java和C在很多基础语法上非常相似,比如基本的数据类型,循环以及条件分支语句,数组的遍历等. ...
- 2018.10.09 NOIP模拟 世界杯(图论+set优化)
传送门 貌似是防akakak题? 不是很清楚. 事实上如果两个人没有严格的大小关系,我们给他们两个连一条边. 这样可以构成很多连通块. 而且对于连通块a,ba,ba,b,aia_iai和bjb_jb ...
- 微信小程序 发送模版消息
微信小程序开发之发送模板消息 1,小程序wxml页面form表单添加 report-submit="true" <form bindsubmit="sub" ...
- 第九章:叹词(L'interjection )
➊叹词的使用词类 .拟声词.如: Ah !啊!呀!哎! Hein !嗯!呣!哎! Paf !啪!叭! Pouf !扑通(重物坠地声) Euh ...
- 【Unity】2.0 第2章 Unity编辑器和基本操作
分类:Unity.C#.VS2015 创建日期:2016-03-26 本章要点: 1.掌握Unity 5.3.4编辑器视图和菜单项及其含义,这是入门的最基础部分,必须掌握. 2.了解最基本的操作,先学 ...
- Myeclipse2014的Preview乱码问题
1.问题图样 2.问题探究:之前的版本没有这个问题,正常服务器部署也没有问题,而且改正了工程的编码设置 JSP的编码方式 3.问题解决:问题还是没有解决,最后找到了方法,似乎是跟本地编码反冲 选中pr ...
- js函数预编译
function fn(a){ console.log(a); var a = 123; function a(){} console.log(a); var b = function(){} con ...
- C#-安全
分为两种,代码访问安全,基于角色的安全性. 代码访问安全.是代码告诉.net框架,自己(代码)正确执行,需要的权限,.net框架手动分配代码可执行操作方面的权限,代码可列出调用自己需要的权限集合. 基 ...
- web问题
模拟form提交过程中form(hidden)时:The frame requesting access has a protocol of "http", the frame b ...
- linux系统编程之文件与IO(一):文件描述符、open,close
什么是IO? 输入/输出是主存和外部设备之间拷贝数据的过程 设备->内存(输入操作) 内存->设备(输出操作) 高级I/O ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的 ...