UOJ#7. 【NOI2014】购票 点分治 斜率优化 凸包 二分
原文链接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】购票 点分治 斜率优化 凸包 二分的更多相关文章
- BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化
BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参 ...
- 【BZOJ3672】[Noi2014]购票 树分治+斜率优化
[BZOJ3672][Noi2014]购票 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- UOJ#7 NOI2014 购票 点分治+凸包二分 斜率优化DP
[NOI2014]购票 链接:http://uoj.ac/problem/7 因为太麻烦了,而且暴露了我很多学习不扎实的问题,所以记录一下具体做法. 主要算法:点分治+凸包优化斜率DP. 因为$q_i ...
- 【BZOJ-3672】购票 树分治 + 斜率优化DP
3672: [Noi2014]购票 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1177 Solved: 562[Submit][Status][ ...
- [NOI2014]购票 「树上斜率优化」
首先易得方程,且经过变换有 $$\begin{aligned} f_i &= \min\limits_{dist_i - lim_i \le dist_j} \{f_j + (dist_i - ...
- BZOJ3672 [Noi2014]购票 【点分治 + 斜率优化】
题目链接 BZOJ3672 题解 如果暂时不管\(l[i]\)的限制,并假使这是一条链 设\(f[i]\)表示\(i\)节点的最优答案,我们容易得到\(dp\)方程 \[f[i] = min\{f[j ...
- 【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 ...
- [BZOJ3672][UOJ#7][NOI2014]购票
[BZOJ3672][UOJ#7][NOI2014]购票 试题描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化
BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化 Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券 ...
随机推荐
- Linux命令_sed
1.替换(将"xxx"替换成"yyy") 现有文件pets.txt 要将其中的"my"替换为"your",可以这样替换, ...
- python放弃篇(Django/爬虫)
第一篇:Django系列 第二篇:爬虫系列 待续……
- 最小生成树(kruskal算法)
首先明确三个概念: 1.最小生成树的特点? 答:假设某个连通网络由n个顶点组成,则其生成树必含n个顶点和n-1条边,而最小生成树的n-1条有个要求:总和最小. 2.并查集的运用? 答:在该问题中,首先 ...
- PC端判断浏览器类型及移动端判断移动设备类型
浏览器代理检测,可以检测出来用户使用的浏览器类型,也可以检测浏览器所在的操作系统 navigator.userAgent (1).判断浏览器类型 var t = navigator.userAgent ...
- SVN clean失败解决方法
一.问题描述 1.svn 更新或者提交时,报错:svn cleanup failed–previous operation has not finished; run cleanup if it wa ...
- C#创建 WebApi 项目
做web api 可以参考一下网友 C#进阶系列——WebApi 接口参数不再困惑:传参详解 - 懒得安分 - 博客园https://www.cnblogs.com/landeanfen/p/5337 ...
- python 中 dlib库的安装
安装 dlib 库的时候需要用到 CMake 进行本地编译,而Cmake又是基于Visual Studio运行的,我在装这个库的时候,各种找不到教程,就想着分享一下自己的经验. 32位 python3 ...
- *42. Trapping Rain Water 接雨水
1. 原始题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这 ...
- MailKit系列之转发电子邮件
原文:http://www.it1352.com/429181.html 问题 我尝试通过MailKit访问一个IMAP账号,我设法下载邮件(作为的MimeMessage),并在某些时候我需要转发给其 ...
- springMVC上传
1.页面 2.开始上传按钮对应的JS 3.添加文件按钮的方法,下图中1是从fast中取到的文件名称,2是文件图片的路径 下面就是后台的一些类.方法等 4.bean层,生成的get和set方法我就不写了 ...