BZOJ3672 : [Noi2014]购票
设d[i]表示i到1的距离
f[i]=w[i]+min(f[j]+(d[i]-d[j])*v[i])=w[i]+d[i]*v[i]+min(-d[j]*v[i]+f[j])
对这棵树进行点分治,每次递归时的根为x,重心为rt
如果x==rt,则把树中所有点用x暴力更新,然后递归分治
否则,先递归分治x的那部分子树,将树中每个点按照能走到的最远处的深度从大到小排序
然后将rt到x路径上所有点维护一个凸壳,依次加入直线
对于树中每一个点,在凸壳上二分更新答案
最后再递归分治其它子树
#include<cstdio>
#include<algorithm>
#define N 200010
typedef long long ll;
int n,i,x,g[N],nxt[N<<1],v[N<<1],ok[N<<1],ed=1,son[N],f[N],size,now,fa[N];
int q[N],all[N],t,cnt;
ll w[N<<1],ans[N],d[N],W[N],V[N],lim[N],z;
inline bool cmp(int x,int y){return lim[x]<lim[y];}
inline void add(int x,int y,ll z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],ok[ed]=1,g[x]=ed;}
inline void up(ll&x,ll y){if(x>y)x=y;}
inline double pos(int x,int y){return (double)(ans[y]-ans[x])/(double)(d[y]-d[x]);}
void findroot(int x,int pre){
son[x]=1;f[x]=0;
for(int i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=pre){
findroot(v[i],x),son[x]+=son[v[i]];
if(son[v[i]]>f[x])f[x]=son[v[i]];
}
if(size-son[x]>f[x])f[x]=size-son[x];
if(f[x]<f[now])now=x;
}
inline void use(int x,int y){if(d[y]>=lim[x])up(ans[x],W[x]+ans[y]-d[y]*V[x]);}
inline void deal(int x){
if(!t)return;
int l=1,r=t-1,fin=t,mid;
while(l<=r){
mid=(l+r)>>1;
if((double)V[x]>=pos(q[mid],q[mid+1]))r=(fin=mid)-1;else l=mid+1;
}
use(x,q[fin]);
}
void dfs(int x){
W[x]+=d[x]*V[x];lim[x]=d[x]-lim[x];
for(int i=g[x];i;i=nxt[i])if(v[i]!=fa[x])d[v[i]]=d[fa[v[i]]=x]+w[i],dfs(v[i]);
}
void cal(int x,int pre){
all[++cnt]=x;
for(int i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=pre)cal(v[i],x);
}
void cal2(int x,int y){
use(x,y);
for(int i=g[x];i;i=nxt[i])if(ok[i]&&v[i]!=fa[x])cal2(v[i],y);
}
void solve(int x){
f[0]=size=son[x],findroot(x,now=0);
int rt=now,i;
if(rt!=x){
for(i=g[rt];i;i=nxt[i])if(v[i]==fa[rt]){ok[i]=ok[i^1]=0,solve(x);break;}
for(cnt=t=0,i=g[rt];i;i=nxt[i])if(ok[i])cal(v[i],rt);
for(std::sort(all+1,all+cnt+1,cmp),i=fa[rt];i!=fa[x];i=fa[i])use(rt,i);
for(i=rt;cnt;deal(all[cnt--]))for(;i!=fa[x];i=fa[i])if(d[i]>=lim[all[cnt]]){
while(t>1&&pos(i,q[t])>pos(q[t],q[t-1]))t--;
q[++t]=i;
}else break;
for(i=g[rt];i;i=nxt[i])if(ok[i])ok[i^1]=0,solve(v[i]);
}else for(i=g[x];i;i=nxt[i])if(ok[i])ok[i^1]=0,cal2(v[i],x),solve(v[i]);
}
int main(){
scanf("%d%d",&n,&i);
for(i=2;i<=n;ans[i++]=1LL<<61)scanf("%d%lld%lld%lld%lld",&x,&z,&V[i],&W[i],&lim[i]),add(x,i,z),add(i,x,z);
son[1]=n,dfs(1),solve(1);
for(i=2;i<=n;i++)printf("%lld\n",ans[i]);
return 0;
}
BZOJ3672 : [Noi2014]购票的更多相关文章
- bzoj千题计划251:bzoj3672: [Noi2014]购票
http://www.lydsy.com/JudgeOnline/problem.php?id=3672 法一:线段树维护可持久化单调队列维护凸包 斜率优化DP 设dp[i] 表示i号点到根节点的最少 ...
- [BZOJ3672][Noi2014]购票 斜率优化+点分治+cdq分治
3672: [Noi2014]购票 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1749 Solved: 885[Submit][Status][ ...
- BZOJ3672: [Noi2014]购票【CDQ分治】【点分治】【斜率优化DP】
Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...
- BZOJ3672 [Noi2014]购票 【点分治 + 斜率优化】
题目链接 BZOJ3672 题解 如果暂时不管\(l[i]\)的限制,并假使这是一条链 设\(f[i]\)表示\(i\)节点的最优答案,我们容易得到\(dp\)方程 \[f[i] = min\{f[j ...
- BZOJ3672: [Noi2014]购票(CDQ分治,点分治)
Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树 ...
- BZOJ3672: [Noi2014]购票(dp 斜率优化 点分治 二分 凸包)
题意 题目链接 Sol 介绍一种神奇的点分治的做法 啥?这都有根树了怎么点分治?? 嘿嘿,这道题的点分治不同于一般的点分治.正常的点分治思路大概是先统计过重心的,再递归下去 实际上一般的点分治与统计顺 ...
- bzoj3672: [Noi2014]购票(树形DP+斜率优化+可持久化凸包)
这题的加强版,多了一个$l_i$的限制,少了一个$p_i$的单调性,难了好多... 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ $\frac {f(j) ...
- [BZOJ3672][UOJ#7][NOI2014]购票
[BZOJ3672][UOJ#7][NOI2014]购票 试题描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- 【BZOJ3672】[Noi2014]购票 树分治+斜率优化
[BZOJ3672][Noi2014]购票 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
随机推荐
- Action的动态调用方法
Action执行的时候并不一定要执行execute方法,我们可以指定Action执行哪个方法: 1. 方法一(通过methed属性指定执行方法): 可以在配置文件中配置Action的时候用method ...
- svn 设置
\Release *\Debug *\bin *\Bin *\obj *\_ReSharper* *\.hg *.ReSharper *.resharper *\Generated_Code *\VB ...
- 30.赋值运算符重载函数[Assign copy constructor]
[问题] 给出如下CMyString的声明,要求为该类型添加赋值运算符函数. C++ Code 1234567891011 class CMyString { public: CMyS ...
- cocos2d-x如何解决图片显示模糊问题
转载http://zhidao.baidu.com/link?url=JTUKP5quGfMQixLZSvtC2XlKMkQDyQbYW72_DRyD6KDRpkLs8_6poQtKkwsyqzU8q ...
- codeforces 489B. BerSU Ball 解题报告
题目链接:http://codeforces.com/problemset/problem/489/B 题目意思:给出 n 个 boys 的 skills 和 m 个 girls 的 skills,要 ...
- Ubuntu下用命令行快速打开各类型文件
在Ubuntu下,通常用命令行打开文本文件,比如用命令gedit.more.cat.vim.less.但当需要打开其他格式文件时,比如pdf. jpg.mp3格式文件,咱们通常做法是进入到文件所在的目 ...
- NEFU 1142 表哥的面包
表哥的面包 Problem:1142 Time Limit:1000ms Memory Limit:65535K Description 可爱的表哥遇到了一个问题,有一个长为N(1≤N≤10^18)的 ...
- 二、JavaScript语言--JS基础--JavaScript进阶篇--函数
1.什么是函数 函数的作用,可以写一次代码,然后反复地重用这个代码. 如:我们要完成多组数和的功能. var sum; sum = 3+2; alert(sum); sum=7+8 ; alert(s ...
- ASP.NET MVC那些事
MVC的由来: 在MVC模式之前,View界面的呈现.用户交互操作的捕捉与相应.业务流程的执行以及数据的存储等都是在一起的,这种设计模式叫自治视图. 这重设计模式主要存在三大弊端: 重用性:业务逻辑与 ...
- linux中断申请之request_threaded_irq
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=21977330&id=3755609 在linux里,中断处理分 ...