重写一遍很久以前写过的题。

  考虑链上的问题。容易想到设f[i]为i到1的最少购票费用,转移有f[i]=min{f[j]+(dep[i]-dep[j])*p[i]+q[i]} (dep[i]-dep[j]<=l[i])。套路的考虑若j转移优于k(dep[j]>dep[k]),则f[j]-dep[j]*p[i]<f[k]-dep[k]*p[i],f[j]-f[k]<(dep[j]-dep[k])*p[i],(f[j]-f[k])/(dep[j]-dep[k])<p[i]。若没有l[]的限制,对(dep[],f[])维护一个下凸壳即可。加入l[]的限制后,考虑使用cdq分治,右侧按dep[]-l[]从大到小排序,更新点时将新增的可以用来更新的点加入凸壳,并在凸壳上二分。

  拓展到树上,通过点分治实现一个树上cdq即可,同理要先处理靠近根的部分。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200010
#define int long long
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,p[N],t,fa[N],w[N],v[N],lim[N],deep[N],f[N],size[N],q[N],u[N],cnt2;
bool flag[N];
struct data{int to,nxt,len;
}edge[N<<1];
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k])
{
deep[edge[i].to]=deep[k]+edge[i].len;
dfs(edge[i].to);
}
}
void make(int k,int from)
{
size[k]=1;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from&&!flag[edge[i].to])
{
make(edge[i].to,k);
size[k]+=size[edge[i].to];
}
}
int findroot(int k,int from,int s)
{
int mx=0;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from&&!flag[edge[i].to]&&size[edge[i].to]>size[mx]) mx=edge[i].to;
if ((size[mx]<<1)>s) return findroot(mx,k,s);
else return k;
}
void build(int k,int from,int *id,int &cnt)
{
id[++cnt]=k;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from&&!flag[edge[i].to]&&deep[edge[i].to]<deep[k]) build(edge[i].to,k,id,cnt);
}
long double slope(int x,int y){return (long double)(f[x]-f[y])/(deep[x]-deep[y]);}
void get(int k,int from)
{
u[++cnt2]=k;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from&&!flag[edge[i].to]) get(edge[i].to,k);
}
bool cmp(const int&a,const int&b)
{
return deep[a]-lim[a]>deep[b]-lim[b];
}
void solve(int k)
{
make(k,k);k=findroot(k,k,size[k]);flag[k]=1;
int id[N],cnt;id[cnt=1]=k;
for (int i=p[k];i;i=edge[i].nxt)
if (!flag[edge[i].to]&&deep[edge[i].to]<deep[k])
{
build(edge[i].to,edge[i].to,id,cnt);
solve(edge[i].to);
}
for (int i=2;i<=cnt;i++) if (deep[k]-deep[id[i]]<=lim[k]) f[k]=min(f[k],f[id[i]]+w[k]*(deep[k]-deep[id[i]])+v[k]);
cnt2=0;
for (int i=p[k];i;i=edge[i].nxt)
if (!flag[edge[i].to]) get(edge[i].to,edge[i].to);
sort(u+1,u+cnt2+1,cmp);
int t=0,tail=0;
for (int i=1;i<=cnt2;i++)
{
while (t<cnt&&deep[id[t+1]]>=deep[u[i]]-lim[u[i]])
{
while (tail>1&&slope(id[t+1],q[tail])>slope(q[tail],q[tail-1])) tail--;
q[++tail]=id[++t];
}
if (tail)
{
int l=1,r=tail-1,ans=tail;
while (l<=r)
{
int mid=l+r>>1;
if (slope(q[mid+1],q[mid])<w[u[i]]) ans=mid,r=mid-1;
else l=mid+1;
}
f[u[i]]=min(f[u[i]],f[q[ans]]+w[u[i]]*(deep[u[i]]-deep[q[ans]])+v[u[i]]);
}
}
cnt=0;
for (int i=p[k];i;i=edge[i].nxt)
if (!flag[edge[i].to]) solve(edge[i].to);
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();read();
for (int i=2;i<=n;i++)
{
fa[i]=read();
addedge(fa[i],i,read());
addedge(i,fa[i],0);
w[i]=read(),v[i]=read(),lim[i]=read();
}
dfs(1);
memset(f,60,sizeof(f));f[1]=0;
solve(1);
for (int i=2;i<=n;i++) printf(LL,f[i]);
return 0;
}

  

UOJ #7 NOI2014购票(点分治+cdq分治+斜率优化+动态规划)的更多相关文章

  1. [BZOJ3672][UOJ#7][NOI2014]购票

    [BZOJ3672][UOJ#7][NOI2014]购票 试题描述  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.       ...

  2. 【BZOJ3672】【NOI2014】购票(线段树,斜率优化,动态规划)

    [BZOJ3672][NOI2014]购票(线段树,斜率优化,动态规划) 题解 首先考虑\(dp\)的方程,设\(f[i]\)表示\(i\)的最优值 很明显的转移\(f[i]=min(f[j]+(de ...

  3. UOJ#7 NOI2014 购票 点分治+凸包二分 斜率优化DP

    [NOI2014]购票 链接:http://uoj.ac/problem/7 因为太麻烦了,而且暴露了我很多学习不扎实的问题,所以记录一下具体做法. 主要算法:点分治+凸包优化斜率DP. 因为$q_i ...

  4. BZOJ3672: [Noi2014]购票【CDQ分治】【点分治】【斜率优化DP】

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

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

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

  6. 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp

    题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...

  7. UOJ 7 NOI2014 购票

    题意:给一棵树计算一下各个点在距离限制下以一定的费用公式通过不停地到祖先最后到达一号点的最小花费. 第一种做法:线段树维护带修凸壳.显然的,这个公式计算是p*x+q 所以肯定和斜率有关系.然后这题的d ...

  8. NOI 2007 货币兑换Cash (bzoj 1492) - 斜率优化 - 动态规划 - CDQ分治

    Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...

  9. [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解

    原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...

随机推荐

  1. MGI数据库挖掘 | MGI-Mouse Genome Informatics | InWeb database

    做生物信息,遗传发育,分析数据的时候总是要narrow down分析范围,高通量数据尤其是基因表达,在庞大的confounder面前,缩小分析范围是必须的,否则你会一直在混沌中游荡. 看一篇文章:20 ...

  2. Spatial-Temporal Relation Networks for Multi-Object Tracking

    Spatial-Temporal Relation Networks for Multi-Object Tracking 2019-05-21 11:07:49 Paper: https://arxi ...

  3. iTop汉化

  4. 关于Android8.0 静态注册广播 行为变更的说明。

    Andorid 8.0 对广播的使用做了变更. 当广播接收器使用静态注册方式使用时,除了一些例外,这个接收器接收不到隐式广播. 注意这个“隐式”是重点. 看了网上几篇文章,对这个变更理解有误.错误的理 ...

  5. RabbitMQ之Fanout交换器模式开发

    Fanout模式,即广播模式,一个发送到交换机的消息会被转发到与该交换机绑定的所有队列上. 一.Provider 配置文件 spring.application.name=provider sprin ...

  6. iptables保存规则(ubuntu和centos)

    1.Ubuntu 首先,保存现有的规则: iptables-save > /etc/iptables.rules 然后新建一个bash脚本,并保存到/etc/network/if-pre-up. ...

  7. git---分支的合并

    git使用分支也可进行多人协作开发. 一.创建分支 git branch zhaozilong 创建一个 zhaozilong 的分支 二.查看所有的分支 git branch -a :查看当前的所有 ...

  8. asp中出现“错误 '80040e14' FROM 子句语法错误”原因

    当你的sql语句中出现 “错误 '80040e14' FROM 子句语法错误.”错误时,请注意了,那有可能是你的表名的命名不规范造成的,比如你的表名是“user”那么这杨的表名是不行的,那么在sql语 ...

  9. Python3入门(十三)——连接数据库

    以Mysql为例: 要操作关系数据库,首先需要连接到数据库,一个数据库连接称为Connection: 连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结 ...

  10. Spring Cloud 如何实现服务间的调用 4.2.3

      如果存在多个服务时,要怎么通过注册中心来实现服务之间的调用呢?接下来将通过一个用户和订单之间的调用案例,来演示Eureka Server中服务之间的调用. 搭建订单服务工程 在父工程xcservi ...