原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ7.html

题解

这题是Unknown的弱化版。

如果这个问题出在序列上,那么显然可以CDQ分治 + 斜率优化 + 凸包上二分来做。

那么它出在树上?

点分治。

写挂了好多地方调了好久,自闭了。

代码

#pragma GCC optimize("Ofast","inline")
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
#define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\
For(_v2,L,R)printf("%d ",a[_v2]);puts("");
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=200005;
const LL INF=1e18;
int n,type;
vector <int> e[N];
int fa[N];
LL d[N],p[N],q[N],lim[N];
LL dp[N];
int size[N],mx[N];
int RT,Size;
int vis[N];
void get_root(int x,int pre){
size[x]=1,mx[x]=0;
for (auto y : e[x])
if (y!=pre&&!vis[y]){
get_root(y,x);
size[x]+=size[y];
mx[x]=max(mx[x],size[y]);
}
mx[x]=max(mx[x],Size-size[x]);
if (!RT||mx[x]<mx[RT])
RT=x;
}
struct Point{
LL x,y;
Point(){}
Point(LL _x,LL _y){
x=_x,y=_y;
}
}a[N];
int top;
vector <int> id;
LL Ask(LL p,LL lim){
if (!top)
return INF;
int L=1,R=top-1,mid;
LL ans=a[top].y-a[top].x*p;
while (L<=R){
mid=(L+R)>>1;
if (p*(a[mid].x-a[mid+1].x)>=a[mid].y-a[mid+1].y)
R=mid-1,ans=min(ans,a[mid].y-a[mid].x*p);
else
L=mid+1;
}
return ans;
}
bool cross(Point a,Point b,Point c){
return (__int128)(b.x-a.x)*(c.y-a.y)-(__int128)(c.x-a.x)*(b.y-a.y)<0;
}
void Ins(Point p){
while (top>1&&!cross(a[top-1],a[top],p))
top--;
a[++top]=p;
}
void upd_dp(int x){
dp[x]=min(dp[x],Ask(p[x],lim[x])+q[x]+p[x]*d[x]);
}
vector <int> s;
void Get(int x,int pre){
s.pb(x);
for (auto y : e[x])
if (y!=pre&&!vis[y])
Get(y,x);
}
bool cmp(int a,int b){
return lim[a]>lim[b];
}
void solve(int x){
RT=0,get_root(x,0),x=RT;
vector <int> id;
id.clear();
for (int i=x;!vis[i];i=fa[i])
id.pb(i);
vis[x]=1;
int sp=Size-size[x];
if (!vis[fa[x]]){
Size=size[fa[x]]>size[x]?sp:size[fa[x]];
solve(fa[x]);
}
for (auto y : id)
if (y!=x&&d[y]>=lim[x])
dp[x]=min(dp[x],dp[y]+p[x]*(d[x]-d[y])+q[x]);
s.clear();
for (auto y : e[x])
if (!vis[y]&&y!=fa[x])
Get(y,x);
sort(s.begin(),s.end(),cmp);
int i=0;
top=0;
for (auto x : id){
while (i<s.size()&&lim[s[i]]>d[x])
upd_dp(s[i++]);
Ins(Point(d[x],dp[x]));
}
while (i<s.size())
upd_dp(s[i++]);
for (auto y : e[x])
if (!vis[y]&&y!=fa[x]){
Size=size[y]>size[x]?sp:size[y];
solve(y);
}
}
int main(){
n=read(),type=read();
For(i,2,n){
fa[i]=read();
d[i]=read()+d[fa[i]];
p[i]=read();
q[i]=read();
lim[i]=d[i]-read();
e[i].pb(fa[i]),e[fa[i]].pb(i);
dp[i]=INF;
}
vis[0]=1,Size=n;
solve(1);
For(i,2,n)
printf("%lld\n",dp[i]);
return 0;
}

  

UOJ#7. 【NOI2014】购票 点分治 斜率优化 凸包 二分的更多相关文章

  1. BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化

    BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化 Description  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参 ...

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

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

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

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

  4. 【BZOJ-3672】购票 树分治 + 斜率优化DP

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

  5. [NOI2014]购票 「树上斜率优化」

    首先易得方程,且经过变换有 $$\begin{aligned} f_i &= \min\limits_{dist_i - lim_i \le dist_j} \{f_j + (dist_i - ...

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

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

  7. 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp

    题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...

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

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

  9. BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化

    BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化 Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券 ...

随机推荐

  1. python全栈开发中级班全程笔记(第二模块)第 二 部分:函数基础(重点)

    python学习笔记第二模块         第二部分    :    函数(重点) 一.函数的作用.定义 以及语法 1.函数的作用 2.函数的语法和定义 函数:来源于数学,但是在编程中,函数这个概念 ...

  2. Windows下U盘管理程序

    一个操作系统的作业,生成的程序需要使用管理员权限运行,参考了很多网上的代码,如果打开错误,请修改字符集为使用多字节字符集,并且调整为release模式. 作业的内容如下: 任务操作系统API应用体验与 ...

  3. 享元模式-Flyweight(Java实现)

    享元模式-Flyweight 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. 本文中的例子如下: 使用享元模式: 小明想看编程技术的书, ...

  4. 【转】Redis学习笔记(四)如何用Redis实现分布式锁(1)—— 单机版

    原文地址:http://bridgeforyou.cn/2018/09/01/Redis-Dsitributed-Lock-1/ 为什么要使用分布式锁 这个问题,可以分为两个问题来回答: 为什么要使用 ...

  5. arcgis图层 GraphicsLayer与FeatureLayer

    什么是图层 图层是用来在 ArcGIS 产品套件中显示地理数据集的机制.每个图层代表一种数据集(可以是地图服务.图形或是矢量数据),并指定该数据集是如何描绘使用一组属性的. 包含一个地图控件的每个应用 ...

  6. python接收axios的post请求,并处理后返回数据

    公司的python工程师不会js和python数据交互,所以我就去试了一下. 首先安装python,django框架和django-cors-headers. python官网下载,按提示操作,记住最 ...

  7. 13、Ajax的使用

    一.AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. a).AJAX = 异步 JavaScript 和 XML. b).AJAX 是一种用于创建快速动态网页的技术. 通过在后 ...

  8. 迅为IMX6Q PLUS开发板烧写Android6.0系统方法

    平台:迅为IMX6Q PLUS开发板工具:MfgTool2 工具 镜像文件在光盘目录“03 镜像_android 6.0.1 文件系统”下.其中商业级核心板为 2G内存镜像,工业级核心板为 1G 内存 ...

  9. 1、Altium Designer 入门

    一.新建工程 File-->new-->Project-->newPCB Project 1.添加原理图 在Project面板选中项目,右键Add New to Project--& ...

  10. [经验交流] 试用 grafana 报警功能

    1. grafana 概述 grafana 是一款优秀的数据展示工具,几乎是各类时序数据库的前端标配系统.grafana 在V4版本中已经加入了报警功能. 2. influxdb 概述 influxd ...