貌似网上大部分题解都是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+可持久化凸包的更多相关文章

  1. 【bzoj3672】[Noi2014]购票 斜率优化dp+CDQ分治+树的点分治

    题目描述  给出一棵以1为根的带边权有根树,对于每个根节点以外的点$v$,如果它与其某个祖先$a$的距离$d$不超过$l_v$,则可以花费$p_vd+q_v$的代价从$v$到$a$.问从每个点到1花费 ...

  2. [NOI2014]购票 --- 斜率优化 + 树形DP + 数据结构

    [NOI2014]购票 题目描述 今年夏天,NOI在SZ市迎来了她30周岁的生日. 来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每 ...

  3. [NOI2014]购票(斜率优化+线段树)

    题目描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的父亲用道路连接 ...

  4. [BZOJ3672][Noi2014]购票 斜率优化+点分治+cdq分治

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1749  Solved: 885[Submit][Status][ ...

  5. [NOI2014]购票——斜率优化+树链剖分+线段树

    建议到UOJ上去交 题解 一眼\(DP\),先把转移方程写出来 设\(dp[i]\)为从点\(i\)出发到点\(1\)的最小费用,那么存在转移 \[f[i]=min\{f[j]+(d[i]-d[j]) ...

  6. BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)

    BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...

  7. 斜率优化DP学习笔记

    先摆上学习的文章: orzzz:斜率优化dp学习 Accept:斜率优化DP 感谢dalao们的讲解,还是十分清晰的 斜率优化$DP$的本质是,通过转移的一些性质,避免枚举地得到最优转移 经典题:HD ...

  8. 【学习笔记】动态规划—斜率优化DP(超详细)

    [学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...

  9. HDU3507 Print Article(斜率优化dp)

    前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...

随机推荐

  1. java判断字符串是否为数字,包括负数

    /** * 判断是否为数字,包含负数情况 * @param str * @return */ private boolean isNumeric(String str){ Boolean flag = ...

  2. sql join用法(转)

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...

  3. POJ 2728 Desert King (最优比率树)

    题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,现在要求方案使得费用与距离的比值最小,很显然,这个题目 ...

  4. 如何在eclipse的配置文件里指定jdk路径

    转载自:https://blog.csdn.net/gnail_oug/article/details/51925804:个人做了些小修改. 今天下载了eclipse4.6版本,打开时报Version ...

  5. 7) mvn dependency:tree

    http://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html mvn dependency:tree 查看 <de ...

  6. 10.N个整数中查找是否相加为K[深度搜索]

    /*摘自书本,这种算法很绕!*/ #include <iostream> using namespace std; ,,,}; ; bool dfs(int i,int sum) { if ...

  7. iOS平台设置系统状态栏(通知栏、顶部状态栏)样式背景颜色或透明

    5+App开发 状态栏 配置系统状态栏样式 iOS平台可支持对系统状态栏样式的配置,在应用manifest.json文件的plus->distribute->apple下添加UIStatu ...

  8. Robotframework 简介及工作原理

    下面通过官网和网上资料来简单介绍下Robotframework及其工作原理. 官方说明: Robot Framework is a generic test automation framework ...

  9. Python学习-20.Python的Urllib模块

    除了 Http 模块可以模拟 Http 请求外,使用 Urllib 模块也是可以模拟 Http 请求的,只不过功能相对弱一点. import urllib.request opener = urlli ...

  10. linux与unix时间戳互转

    linux与unix时间戳互转 今天在消费kafka数据时遇到了这样一个问题,kafka数据中所有的数据时间戳格式都是unix上时间戳的格式,例如:1505786829101,看到这个时间戳真的是头都 ...