感觉是noi2014中最有价值的一道题了

我们先考虑链上这个问题怎么做……

如果没限制,那就是SB的斜率优化

我们可以得到这个式子(f[j]-f[k])/(s[j]-s[k])<p[i]

点横坐标是单调的,我们只要维护凸壳然后二分即可

有距离限制?好像不好弄,不过我们记得cash那道坐标不单调的题我们是可以用cdq分治的

这道题也一样,划分,考虑左半部分对右半部分的影响

我们只要对右半部分距离限制排序然后依次加点维护凸壳然后二分即可

换到树上来那就是点分治啦,

我们找重心,先做重心子树外(就是包含根的那部分),做完之后

考虑重心的祖先对子树的影响,我们完全可以如法炮制

然后不断向下递归处理即可

这样noi2014的传统题就做完啦!

 const inf=;
eps=1e-10; type node=record
po,next:longint;
end;
point=record
x,y:int64;
end; var h,fp,p,fa,mx,s,q,b:array[..] of longint;
a:array[..] of point;
cut:array[..] of boolean;
e:array[..] of node;
w,f,d,kp,bp,lim:array[..] of int64;
x,t,i,len,n,ty,r:longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure min(var a:int64; b:int64);
begin
if a>b then a:=b;
end; procedure add(x,y:longint);
begin
inc(len);
e[len].po:=y;
e[len].next:=p[x];
p[x]:=len;
end; procedure bfs(st:longint);
var i,f,x,y:longint;
begin
f:=;
r:=;
q[]:=st;
while f<=r do
begin
x:=q[f];
i:=p[x];
while i<> do
begin
if not cut[i] then
begin
inc(r);
q[r]:=e[i].po;
end;
i:=e[i].next;
end;
inc(f);
end;
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; function cmp(i,j:longint):boolean;
begin
exit(lim[i]-d[i]<lim[j]-d[j]);
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;
j:=r;
x:=b[(l+r) shr ];
repeat
while cmp(b[i],x) do inc(i);
while cmp(x,b[j]) do dec(j);
if i<=j then
begin
swap(b[i],b[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; function getk(i,j:longint):extended;
begin
exit((a[i].y-a[j].y)/(a[i].x-a[j].x));
end; function find(l,r,x:longint):longint;
var m:longint;
s1,s2:int64;
begin
while l<r do
begin
m:=(l+r) shr ;
s1:=a[h[m]].y+a[h[m]].x*kp[x];
s2:=a[h[m+]].y+a[h[m+]].x*kp[x];
if s1>s2 then l:=m+
else r:=m;
end;
exit(h[l]);
end; procedure cdq(root:longint);
var i,j,x,mid,m,y:longint;
begin
bfs(root);
if r= then exit;
mid:=;
for i:=r downto do
begin
x:=q[i];
s[x]:=;
mx[x]:=;
j:=p[x];
while j<> do
begin
y:=e[j].po;
if not cut[j] then
begin
s[x]:=s[x]+s[y];
mx[x]:=max(mx[x],s[y]);
end;
j:=e[j].next;
end;
mx[x]:=max(mx[x],r-s[x]);
if mx[x]<mx[mid] then mid:=x;
end;
if root<>mid then
begin
cut[fp[mid]]:=true;
cdq(root);
m:=;
x:=fa[mid];
while x<>root do
begin
inc(m);
a[m].x:=-d[x]; //为了方便改变一下形式
a[m].y:=f[x];
x:=fa[x];
end;
inc(m);
a[m].x:=-d[x];
a[m].y:=f[x]; bfs(mid);
for i:= to r do
b[i]:=q[i];
sort(,r);
t:=;
j:=;
for i:= to r do
begin
x:=b[i];
while (j<=m) and (a[j].x<=lim[x]-d[x]) do
begin
while (t>) and (getk(j,h[t])-eps<getk(h[t],h[t-])) do dec(t);
inc(t);
h[t]:=j;
inc(j);
end;
if t> then
begin
y:=find(,t,x);
min(f[x],a[y].y+kp[x]*(d[x]+a[y].x)+bp[x]);
end;
end;
end;
for i:= to r do
begin
x:=q[i];
if d[x]-d[mid]<=lim[x] then
min(f[x],f[mid]+kp[x]*(d[x]-d[mid])+bp[x]);
end;
i:=p[mid];
while i<> do
begin
if not cut[i] then cdq(e[i].po);
i:=e[i].next;
end;
end; begin
readln(n,ty);
for i:= to n do
begin
readln(fa[i],w[i],kp[i],bp[i],lim[i]);
add(fa[i],i);
fp[i]:=len;
f[i]:=inf;
end;
bfs();
for i:= to r do
begin
x:=q[i];
d[x]:=d[fa[x]]+w[x];
end;
mx[]:=n+;
f[]:=;
cdq();
for i:= to n do
writeln(f[i]);
end.

bzoj3672的更多相关文章

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

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

  2. BZOJ3672 [Noi2014]购票 【点分治 + 斜率优化】

    题目链接 BZOJ3672 题解 如果暂时不管\(l[i]\)的限制,并假使这是一条链 设\(f[i]\)表示\(i\)节点的最优答案,我们容易得到\(dp\)方程 \[f[i] = min\{f[j ...

  3. bzoj3672【NOI2014】购票

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

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

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

  5. 【bzoj3672】购票

    Portal -->bzoj3672 Solution 天知道我是怎么调完的qwq调到天昏地暗系列.. ​ 不管这么多,先尝试列一个最简单的状态转移方程 用\(f[i]\)表示\(i\)点到\( ...

  6. 【BZOJ3672】[Noi2014]购票 树分治+斜率优化

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

  7. 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]) 对这棵树进行点分治,每次递 ...

  8. bzoj千题计划251:bzoj3672: [Noi2014]购票

    http://www.lydsy.com/JudgeOnline/problem.php?id=3672 法一:线段树维护可持久化单调队列维护凸包 斜率优化DP 设dp[i] 表示i号点到根节点的最少 ...

  9. bzoj3672/luogu2305 购票 (运用点分治思想的树上cdq分治+斜率优化dp)

    我们都做过一道题(?)货币兑换,是用cdq分治来解决不单调的斜率优化 现在它放到了树上.. 总之先写下来dp方程,$f[i]=min\{f[j]+(dis[i]-dis[j])*p[i]+q[i]\} ...

随机推荐

  1. C# 数据结构--排序[上]

    概述 看了几天的排序内容,现在和大家分享一些常见的排序方法. 啥是排序? 个人理解的排序:通过对数组中的值进行对比,交换位置最终得到一个有序的数组.排序分为内存排序和外部排序.本次分享排序方法都为内存 ...

  2. 【Vijos】【1164】曹冲养猪

    中国剩余定理 没啥重要的……模板题,中国剩余定理就是解出模线性方程组的一个可行解(好像也是唯一解?) 这是一种神奇的构造方法……明白了为什么这样构造是对的就行了=.=至于怎么想到这种构造方法的……去问 ...

  3. 【BZOJ】【1430】小猴打架

    排列组合 蛮逗的…… 这题题干描述的就一股浓浓的Kruskal的气息……很容易就想到是求一个n个点的完全图的生成树个数,然后由于有序,再乘一个n-1的排列数(n-1条边的全排列)即(n-1)! 但是我 ...

  4. 20160729noip模拟赛zld

    首先显然有多少个奇数,就有多少个回文串是最优的(没有奇数时构造一个回文串 然后有了k个“核心”,把剩下的字符顺序安排到这些的两侧,最后最短的回文串长度就是答案 #include<map> ...

  5. 运用 DataContractSerializer 存储本地对象

    public void Save(string filename,State state) { DataContractSerializer ds = new DataContractSerializ ...

  6. C#调用大漠插件的方法和实例

    大漠插件是一个很不错的东西,在按键精灵和易语言里面用得很多,可以后台找图找字,写游戏自动脚本用得特别多.前面写一个微信的自动脚本,查了一些资料,易语言不太熟悉,按键精灵功能上可能不好实现,就找了些资料 ...

  7. phonegap/cordova 启动页面

    启动phonegap应用时,因为phonegap还在加载一系列的东西,总会出现一段时间的黑屏.解决方法是设置一个启动页面(闪屏)来过渡,让应用的用户体验更好一些. 先讲ios版本的: 首先,你需要准备 ...

  8. 【锋利的JQuery-学习笔记】Tab选项卡的实现

    效果图: 关键点: 1.标签和标签内容都是用<ul><li>实现的,主要是通过Css样式设计成选项卡的模样. 2.用js代码实现点击标签时,标签内容的切换(做法是<div ...

  9. cf 359A 359B

    359A 如果有点在边上则最少两次 没有则最少操作4次 #include <cstdio> #include <cstring> #include <algorithm& ...

  10. mysql数据库主外键级联删除脚本RESTRICT --> CASCADE

    在项目中,我们一般在数据库设计的时候做主外键关联设计,要么就不做.但是这样不符合规范,呵呵. 建立主外键关系的时候,默认是不能级联删除的.而出现往往在删除主表的数据时报错, 需要先删除从表然后再删除主 ...