题意:

给出一颗n个结点的有根树,边有长度;

每个点有可以购票前往长度相差不超过li的它的祖先,票的花费为pi*长度+qi;

当然的,可以的选择多次倒车到达;

求每个点到根的最小花费;

n<=200000;

题解:

这题真的好贴心,数据特殊情况都给你让你特判了2333;

首先一条链的情况都会吧,设f[i]为i到根的最小花费,dis为到根的距离;

转移方程为:f[i]=f[j]+p[i]*(dis[i]-dis[j])+q[i];

斜率优化搞搞就好了;

然而到了树上,和在序列上的思想基本一样;

但是多了很多细节处理;

分治自然是要分的,分的就应该是树的重心;

分治之后呢?

分治之后的树应该是是有根的,因为所有点的DP值都是由树上的祖先更新而来;

所以就用根到分治中心的这条链,去更新所有分治中心的其他子树;

但是和一般的序列上的不同,我们不能处理完凸包再二分去找答案;

那样会有可选的值遗漏;

所以将要更新的点放在一个序列中,按能够到的祖先排序;

排序之后就在这个序列里扫就好了,时间复杂度是O(L*logL);

然后带上树分治的复杂度,总复杂度O(nlog^2n);

细节颇多,树分治的姿势都是不熟嘛;

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 210000
using namespace std;
typedef long long ll;
int next[N],to[N],head[N],tot;
ll val[N];
int fa[N],size[N],st[N],top,qu[N],s,t,G,mi;
ll p[N],q[N],l[N],dis[N],f[N];
bool ban[N];
void add(int x,int y,ll v)
{to[++tot]=y;val[tot]=v;next[tot]=head[x];head[x]=tot;
}
void init(int x)
{size[x]=1;for(int i=head[x];i;i=next[i]){dis[to[i]]=dis[x]+val[i];init(to[i]);size[x]+=size[to[i]];}
}
bool cmp(int a,int b)
{return dis[a]-l[a]>dis[b]-l[b];
}
void getP(int x)
{st[++top]=x;for(int i=head[x];i;i=next[i])if(!ban[to[i]])getP(to[i]);
}
ll find(int x)
{if(s>t) return 0x3f3f3f3f3f3f3f3fll;int l=s,r=t,mid;while(l<=r){mid=l+r>>1;if(mid+1>t||(long double)(f[qu[mid+1]]-f[qu[mid]])/(dis[qu[mid+1]]-dis[qu[mid]])<p[x])r=mid-1;elsel=mid+1;}return f[qu[l]]+p[x]*(dis[x]-dis[qu[l]])+q[x];
}
void getG(int x,int bk)
{size[x]=1;int i,mas=0,temp;for(i=head[x];i;i=next[i]){if(ban[to[i]])   continue;getG(to[i],bk);size[x]+=size[to[i]];mas=max(mas,size[to[i]]);}mas=max(mas,bk-size[x]);if(mas<=mi)mi=mas,G=x;
}
void slove(int x,int y)
{if(size[x]==1)   return ;int i,j,k;for(i=head[y];i;i=next[i])if(!ban[to[i]])ban[to[i]]=1;mi=0x3f3f3f3f;getG(x,size[x]);slove(x,G);top=0;for(i=head[y];i;i=next[i])getP(to[i]);sort(st+1,st+top+1,cmp);s=1,t=0;for(i=1,k=y;i<=top;i++){while(k!=fa[x]&&dis[st[i]]-l[st[i]]<=dis[k]){while(s<t&&(long double)(f[qu[t-1]]-f[qu[t]])/(dis[qu[t-1]]-dis[qu[t]])<(long double)(f[qu[t]]-f[k])/(dis[qu[t]]-dis[k]))t--;qu[++t]=k;k=fa[k];}f[st[i]]=min(f[st[i]],find(st[i]));}for(i=head[y],k=size[x];i;i=next[i]){mi=0x3f3f3f3f;getG(to[i],size[to[i]]);slove(to[i],G);}
}
int main()
{int n,m,i,j,k,x,y;ll v;scanf("%d%d",&n,&m);for(i=2;i<=n;i++){scanf("%d%lld%lld%lld%lld",fa+i,&v,p+i,q+i,l+i);add(fa[i],i,v);}ban[1]=0;init(1);memset(f,0x3f,sizeof(f));f[1]=0;mi=0x3f3f3f3f;getG(1,size[1]);slove(1,G);for(i=2;i<=n;i++)printf("%lld\n",f[i]);return 0;
}

bzoj-3672 购票相关推荐

  1. linux weblogic 防火墙,本地访问weblogic控制台无反应,关闭linux操作系统防火墙

    有时候,我们在Linux操作系统上成功启动了weblogic,也查看了7001端口的状态是开启的.但是访问weblogic控制台没有反应,也没有报错. 使用 netstat -ano | grep 7 ...

  2. CCF CSP 201609-2 火车购票

    题目链接:http://118.190.20.162/view.page?gpid=T46 问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排 ...

  3. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  4. S-T平面图中利用最短路求最小割(BZOJ 1001)

    BZOJ 1001: [BeiJing2006]狼抓兔子 最小割 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢 ...

  5. BZOJ 1124: [POI2008]枪战Maf(构造 + 贪心)

    题意 有 \(n\) 个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪. 因此,对于不同的开枪顺序,最后死的人也不同. 问最 ...

  6. BZOJ 2957楼房重建

    传送门 线段树 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include< ...

  7. BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)

    BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...

  8. bzoj 4871: [Shoi2017]摧毁“树状图”

    4871: [Shoi2017]摧毁"树状图" Time Limit: 25 Sec  Memory Limit: 512 MB Submit: 53  Solved: 9 [Su ...

  9. 【青少年编程】【蓝桥杯】排队购票

    「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 我们将有关编程题目的教学视频已经发布到抖 ...

  10. BZOJ 1592. Making the Grade(思维,数据结构优化DP,以及三个拓展问题)[Usaco2008 Feb]【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 BZOJ简单题合集x 目录 BZOJ 1592. Making the Grade 拓展问题一 拓展问 ...

最新文章

  1. 网站建设初学者一定要清楚网站建设基本因素和流程
  2. LeetCode Range Sum Query 2D - Immutable
  3. [Windows]ping itsafe环境变量
  4. 计算机视觉编程——图像内容分类
  5. adb install 和adb uninstall
  6. CSS Hack汇总(转载)
  7. 几个有用的ASP Function
  8. 怎么把php查询到的值显示到下拉框中_RazorSQL for Mac(数据库工具查询)8.5.3
  9. CC++——库头文件及其作用
  10. 你在成长为一个优秀的程序员吗
  11. Pycharm 加载pygame解决方案
  12. linux bogomips,内核探索:Linux BogoMips 探秘
  13. 远程打开其他电脑的computer management
  14. 基于java的开源游戏引擎
  15. 二战十大致命武器之“喷火”式战斗机
  16. C语言实现求两个数的和
  17. 2021年全球与中国测光表行业市场规模及发展前景分析
  18. 基于 STM32 空气质量检测装置设计
  19. CTF之web学习记录 -- 命令注入
  20. Linux常用命令 实用命令万字总结(转载学习)

热门文章

  1. NVIDIA控制面板不能用的解决方法(先确保显卡硬件正常)
  2. 简单聊一聊有关就业和职业发展的话题
  3. Base64j加密解密、动态代理、正则表达式、单例多例设计模式、枚举、工厂设计模式
  4. Minecraft 1.18.1、1.18.2模组开发 03.生物实体
  5. 使用python进行文件夹的压缩
  6. Unity鼠标键盘事件
  7. 设置win7计算机名字共享,win7文件夹共享【使用模式】
  8. ubuntu通过netplan设置ip
  9. Vue--过滤器(filters)
  10. C语言—一道面试题(品茗股份)