题目链接:购票

  这道题我调了好久啊……主要还是因为这种用\(CDQ\)分治来搞斜率优化的题已经很久没写过了……上一次要追溯到去年暑假去了……

  看下面这些东西之前你需要先自己推出斜率优化的式子……

  这道题我们先来考虑一下如果不是树,在序列上怎么做。用\(CDQ\)分治的思想,先递归处理左半区间,然后用左半区间的值来更新右半区间,最后递归处理右半区间。这样的话,每次递归处理到一个区间,我们只需要考虑这个区间左边的点对右边的点的影响,对左边的点维护一个凸包,每次在凸包上二分最优解即可。

  考虑如何把这个拓展到树上。我们树分治的时候每次是找了一个重心出来,然后递归处理剩下的部分。因此,我们在做这道题的时候,只需先递归处理剩下的子树中重心父亲所在的块,然后更新其他点的答案,最后递归其他联通块即可。注意重心需要单独考虑一下。

  还有一个细节:先把所有祖先拿出来构凸包,然后每次在上面二分是不对的。因为这样可能会出现这种情况:对于一个点\(x\),它的最优决策是\(u\),在\(fa_u\)加入了凸包后点\(u\)会被从凸包中踢掉。但是如果\(x\)只能到\(u\)而到不了\(fa_u\),就挂掉了……因为这里我调了好久……所以我们需要把点抠出来按能够到达的最小深度排序,然后把祖先一个一个往凸包里面加……

  不知道为什么我的程序好慢……

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 200010
#define INF (1ll<<60) using namespace std;
typedef long long llg; int n,fa[maxn],p[maxn],T;
int head[maxn],next[maxn<<1],to[maxn<<1],tt;
llg d[maxn],f[maxn],q[maxn],L[maxn]; struct point{
llg x,y;
bool operator < (const point &h)const{return x>h.x;}
point(llg a=0,llg b=0):x(a),y(b){}
}s[maxn]; struct Convex{//维护下凸包
point s[maxn];int ls;
double R(point a,point b){return (double)(b.y-a.y)/(b.x-a.x);}
void push(point x){
while(ls>1 && R(s[ls-1],s[ls])<=R(s[ls],x)) ls--;
s[++ls]=x;
}
llg find(int x){//二分斜率
if(!ls) return INF;
int l=1,r=ls,mid;
while(l<r){
mid=(l+r)>>1;
if(R(s[mid],s[mid+1])<x) r=mid;
else l=mid+1;
}
return s[l].y-1ll*x*s[l].x;
}
}tu; void link(int x,int y){
to[++tt]=y;next[tt]=head[x];head[x]=tt;
to[++tt]=x;next[tt]=head[y];head[y]=tt;
} int a[maxn],la,val[maxn],siz[maxn],dax[maxn];
bool vis[maxn]; void dfs(int u){
vis[u]=1; a[++la]=u; siz[u]=1; dax[u]=0;
for(int i=head[u],v;v=to[i],i;i=next[i])
if(!vis[v]) dfs(v),siz[u]+=siz[v],dax[u]=max(dax[u],siz[v]);
vis[u]=0;
} void solve(int ff,int fr){
la=0; dfs(ff); int k=a[1],ls=0;
for(int i=1,u;u=a[i],i<=la;i++){
val[u]=max(dax[u],siz[ff]-siz[u]);
if(val[u]<val[k]) k=u;
} vis[k]=1; if(!vis[fa[k]]) solve(fa[k],fr);//先处理父亲 a[la=1]=k;
for(int i=head[k],v;v=to[i],i;i=next[i])
if(!vis[v] && v!=fa[k]) dfs(v);
for(int i=1,u;u=a[i],i<=la;i++) s[i]=point(d[u]-L[u],u);
ls=la; sort(s+1,s+ls+1); la=0;//把所有需要被更新的点抠出来排序 for(int u=fa[k];!vis[u];u=fa[u]) a[++la]=u;
if(fr) a[++la]=fr; tu.ls=0;//上一层的重心没有在上一层考虑,这一层要加进来 for(int i=1,j=1,u;u=s[i].y,i<=ls;i++){//更新
while(j<=la && d[a[j]]>=s[i].x) tu.push(point(d[a[j]],f[a[j]])),j++;
f[u]=min(f[u],tu.find(p[u])+1ll*p[u]*d[u]+q[u]);
} for(int i=head[k],v;v=to[i],i;i=next[i])
if(!vis[v] && v!=fa[k]) solve(v,k);
vis[k]=0;
} int main(){
File("a");
scanf("%d %d",&n,&T);
for(int i=2;i<=n;i++){
scanf("%d %lld",&fa[i],&d[i]);
scanf("%d %lld %lld",&p[i],&q[i],&L[i]);
d[i]+=d[fa[i]]; link(i,fa[i]); f[i]=INF;
}
vis[0]=1; solve(1,0);
for(int i=2;i<=n;i++) printf("%lld\n",f[i]);
return 0;
}

  BZOJ提交链接:BZOJ 3672 购票

UOJ #7 【NOI2014】 购票的更多相关文章

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

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

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

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

  3. UOJ #7 NOI2014购票(点分治+cdq分治+斜率优化+动态规划)

    重写一遍很久以前写过的题. 考虑链上的问题.容易想到设f[i]为i到1的最少购票费用,转移有f[i]=min{f[j]+(dep[i]-dep[j])*p[i]+q[i]} (dep[i]-dep[j ...

  4. UOJ 7 NOI2014 购票

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

  5. [BZOJ3671][UOJ#6][NOI2014]随机数生成器

    [BZOJ3671][UOJ#6][NOI2014]随机数生成器 试题描述 小H最近在研究随机算法.随机算法往往需要通过调用随机数生成函数(例如Pascal中的random和C/C++中的rand)来 ...

  6. [BZOJ3670][UOJ#5][NOI2014]动物园

    [BZOJ3670][UOJ#5][NOI2014]动物园 试题描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学 ...

  7. bzoj 3672: [Noi2014]购票 树链剖分+维护凸包

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 480  Solved: 212[Submit][Status][D ...

  8. BZOJ 3672: [Noi2014]购票( 树链剖分 + 线段树 + 凸包 )

    s弄成前缀和(到根), dp(i) = min(dp(j) + (s(i)-s(j))*p(i)+q(i)). 链的情况大家都会做...就是用栈维护个下凸包, 插入时暴力弹栈, 查询时就在凸包上二分/ ...

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

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

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

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

随机推荐

  1. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第7节: 获取异线程释放的对象

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第七节: 获取异线程释放的对象 上一小节分析了异线程回收对象, 原理是通过与stack关联的WeakOrder ...

  2. golang -- 字符串就地取反

    字符串 定义 在golang中字符串是一种不可变的字节序列,它可以包含任意的数据,包括0值字节,但主要是人类可以阅读的文本.golang中默认字符串被解读为utf-8编码的Unicode码点(文字符号 ...

  3. http跳转https方法:百度云如何让http自动跳转到https【免费SSL证书使用FAQ】

    之前的一篇文章已经给大家提供了免费SSL证书的申请方法,这一篇文章是告诉大家在使用免费的SSL证书时可能会遇到的问题[怎么让http自动跳转到https以及http与https同时使用]的解决方法. ...

  4. 机器学习(一):记一次k一近邻算法的学习与Kaggle实战

    本篇博客是基于以Kaggle中手写数字识别实战为目标,以KNN算法学习为驱动导向来进行讲解. 写这篇博客的原因 什么是KNN kaggle实战 优缺点及其优化方法 总结 参考文献 写这篇博客的原因 写 ...

  5. Performance — 前端性能监控利器

    Performance是一个做前端性能监控离不开的API,最好在页面完全加载完成之后再使用,因为很多值必须在页面完全加载之后才能得到.最简单的办法是在window.onload事件中读取各种数据. 大 ...

  6. xml配置文件特殊符号的处理方法

    2017.7.19遇到问题:偶然出现“认证失败,请重新登录”的现象   在xml中英文问号“?”是可以被正常解析的,但是以下这几种符号是不能正常解析的:分别是“&”.“<”.“>” ...

  7. Daily Scrum (2015/11/3)

    今天我们的爬虫能在pc上成功运行并且把所爬取的数据存到服务器上了!我们已经搭建好数据库,把相关信息存到数据库中,并把数据存到D盘里共享给数据处理小组使用. 成员 今日工作 时间 明日工作 符美潇 完成 ...

  8. Daily Scrum (2015/10/28)

    昨天DEV们完成了一部分代码风格的修整.今晚在与其他组进行交流时我们发现我们的代码是需要在服务器上运行的,而且服务器是需要配置的,而且据说需要花一些时间.所以在编写代码之前PM提出我们应该先把服务器搭 ...

  9. 关于map和hashmap

    今天做的程序猿那题 在公司里面,程序猿经常有一堆todolist要做,而这些todolist是产品经理分配给他们的.但是当程序员遇到不懂技术的产品狗时,就悲剧了.产品经理经常修改他们的todolist ...

  10. apache重写规则 rewrite

    Rewrite规则表达式的说明: . 匹配任何单字符 [chars] 匹配字符串:chars [^chars] 不匹配字符串:chars text1|text2 可选择的字符串:text1或text2 ...