bzoj3672
感觉是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的更多相关文章
- [BZOJ3672][UOJ#7][NOI2014]购票
[BZOJ3672][UOJ#7][NOI2014]购票 试题描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- BZOJ3672 [Noi2014]购票 【点分治 + 斜率优化】
题目链接 BZOJ3672 题解 如果暂时不管\(l[i]\)的限制,并假使这是一条链 设\(f[i]\)表示\(i\)节点的最优答案,我们容易得到\(dp\)方程 \[f[i] = min\{f[j ...
- bzoj3672【NOI2014】购票
题目描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与 ...
- 【BZOJ3672】【NOI2014】购票(线段树,斜率优化,动态规划)
[BZOJ3672][NOI2014]购票(线段树,斜率优化,动态规划) 题解 首先考虑\(dp\)的方程,设\(f[i]\)表示\(i\)的最优值 很明显的转移\(f[i]=min(f[j]+(de ...
- 【bzoj3672】购票
Portal -->bzoj3672 Solution 天知道我是怎么调完的qwq调到天昏地暗系列.. 不管这么多,先尝试列一个最简单的状态转移方程 用\(f[i]\)表示\(i\)点到\( ...
- 【BZOJ3672】[Noi2014]购票 树分治+斜率优化
[BZOJ3672][Noi2014]购票 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- 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]) 对这棵树进行点分治,每次递 ...
- bzoj千题计划251:bzoj3672: [Noi2014]购票
http://www.lydsy.com/JudgeOnline/problem.php?id=3672 法一:线段树维护可持久化单调队列维护凸包 斜率优化DP 设dp[i] 表示i号点到根节点的最少 ...
- bzoj3672/luogu2305 购票 (运用点分治思想的树上cdq分治+斜率优化dp)
我们都做过一道题(?)货币兑换,是用cdq分治来解决不单调的斜率优化 现在它放到了树上.. 总之先写下来dp方程,$f[i]=min\{f[j]+(dis[i]-dis[j])*p[i]+q[i]\} ...
随机推荐
- Could not locate device support files.《This iPhone 5 (Model A1429) is running iOS 7.0.4 (11B554a), which may not be supported by this version of Xcode.》-b
原因:Xcode8 不支持 iOS7 解决方法: 在“/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/De ...
- UVA 10954 Add All 哈夫曼编码
题目链接: 题目 Add All Time Limit:3000MS Memory Limit:0KB 问题描述 Yup!! The problem name reflects your task; ...
- javascript中alert()与console.log()的区别
我们在做js调试的时候使用 alert 可以显示信息,调试程序,alert 弹出窗口会中断程序, 如果要在循环中显示信息,手点击关闭窗口都累死.而且 alert 显示对象永远显示为[object ]. ...
- PHP读取xml之cdata讲解
实例: xss.xml <?xml version="1.0" encoding="UTF-8"?><filters> <f ...
- hdu 4901
一个简单的dp,比赛的时候太坚信自己的小聪明没用二维数组一直WA到死: #include<cstdio> #include<cstring> #define maxn 1009 ...
- unity3d android互调
unityPlayer = new AndroidJavaClass("com.xxx.xxx.MainActivity"); curActivity = unityPlayer. ...
- HDU 4509 湫湫系列故事——减肥记II(暴力模拟即可)
看了题目后,没自己做,直接看别人题解了,这里转一下. 看了之后,突然想起scanf还可以按照自己写的格式输入数据啊,差点连这个都忘记了啊. 注意输入中时间可能有重复的. http://www.cnbl ...
- 1829 A Bug's Life
A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 2016年2月---Javascript
How to Learn JavaScript Properly 如何正确学习JavaScript Learn Intermediate and Advanced JavaScript 书籍: < ...
- unity UGUI动态字体显示模糊
设置Unity中ttf文件的Character为Unicode,点击apply