BZOJ1767/Gym207383I CEOI2009 Harbingers 斜率优化、可持久化单调栈、二分
注:本题在BZOJ上是权限题,在Gym里面也不能直接看,所以只能在VJ上交了……
不难考虑到这是一个\(dp\)。
设\(dep_x\)表示\(x\)在树上的带权深度,\(parent_x\)表示\(x\)的祖先节点集合,\(f_x\)表示点\(x\)的答案
那么
\(f_x = \min\limits_{i \in parent_x}\{f_i + V_x \times (dep_x - dep_i)\} + S_x = \min\limits_{i \in parent_x}\{- dep_i \times V_x + f_i\} + S_x + V_x \times dep_x\)
这是一个典型的斜率优化模型,斜率为\(-dep_i\),截距为\(f_i\),自变量为\(V_x\)。
首先对于树上的一条链,\(V_x\)并不单调,所以我们不能使用单调队列。但是因为边权非负,所以斜率单调不降,也就意味着我们不需要使用平衡树,而只需要使用单调栈+二分就可以解决维护凸包的问题。
再者,因为不是序列上的问题,那么计算到某一个点后,当前的单调栈会被其所有儿子共用,而儿子不止一个,所以我们需要将单调栈持久化以应对多次的使用。使用可持久化线段树解决这个问题。
最后注意:在维护凸包时不能暴力\(pop\)当前不满足条件的直线,而是应该在单调栈上二分找到最后一个在凸包上的直线。这样才能够保证复杂度。
总复杂度为\(O(nlog^2n)\)
下面是一份常数巨大的代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<vector>
#include<cmath>
#define int long long
#define mid ((l + r) >> 1)
#define lch Tree[x].l
#define rch Tree[x].r
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return f ? -a : a;
}
const int MAXN = 1e5 + 7;
struct Edge{
int end , upEd , w;
}Ed[MAXN << 1];
struct line{
int k , b;
line(int _k = 0 , int _b = 0):k(_k) , b(_b){}
};
struct node{
int l , r;
line L;
}Tree[MAXN * 30];
int rt[MAXN] , head[MAXN] , ans[MAXN] , dep[MAXN] , V[MAXN] , S[MAXN] , cnt[MAXN];
int cntN , cntEd , N , maxN;
inline void addEd(int a , int b , int c){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
Ed[cntEd].w = c;
head[a] = cntEd;
}
inline int calc(line l , int x){
return l.k * x + l.b;
}
line getL(int x , int l , int r , int tar){
if(l == r)
return Tree[x].L;
if(mid >= tar)
return getL(lch , l , mid , tar);
return getL(rch , mid + 1 , r , tar);
}
void ins(int &x , int l , int r , int tar , line L){
int t = ++cntN;
Tree[t] = Tree[x];
x = t;
if(l == r){
Tree[t].L = L;
return;
}
if(mid >= tar)
ins(lch , l , mid , tar , L);
else
ins(rch , mid + 1 , r , tar , L);
}
inline int erf(int id , int x){
int L = 1 , R = cnt[id];
while(L < R){
int MID = (L + R) >> 1;
if(calc(getL(rt[id] , 1 , N , MID) , x) > calc(getL(rt[id] , 1 , N , MID + 1) , x))
L = MID + 1;
else
R = MID;
}
return calc(getL(rt[id] , 1 , N , L) , x);
}
inline bool ifpop(line L1 , line L2 , line L3){
return (long double)(L1.b - L2.b) * (L3.k - L1.k) >= (long double)(L1.b - L3.b) * (L2.k - L1.k);
}
inline int erf2(int id , line l){
int L = 1 , R = cnt[id];
while(L < R){
int MID = (L + R) >> 1;
if(ifpop(getL(rt[id] , 1 , N , MID) , getL(rt[id] , 1 , N , MID + 1) , l))
R = MID;
else
L = MID + 1;
}
return L;
}
void dfs(int x , int p){
bool f = 1;
if(x != 1){
rt[x] = rt[p];
cnt[x] = cnt[p];
ans[x] = erf(x , V[x]) + dep[x] * V[x] + S[x];
line p = getL(rt[x] , 1 , N , cnt[x]);
if(p.k == -dep[x])
if(p.b > ans[x])
--cnt[x];
else
f = 0;
if(f)
cnt[x] = erf2(x , line(-dep[x] , ans[x]));
}
if(f)
ins(rt[x] , 1 , N , ++cnt[x] , line(-dep[x] , ans[x]));
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(Ed[i].end != p){
dep[Ed[i].end] = dep[x] + Ed[i].w;
dfs(Ed[i].end , x);
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
N = read();
for(int i = 1 ; i < N ; ++i){
int a = read() , b = read() , c = read();
addEd(a , b , c);
addEd(b , a , c);
}
for(int i = 2 ; i <= N ; ++i){
S[i] = read();
V[i] = read();
}
dfs(1 , 0);
for(int i = 2 ; i <= N ; ++i)
cout << ans[i] << ' ';
return 0;
}
BZOJ1767/Gym207383I CEOI2009 Harbingers 斜率优化、可持久化单调栈、二分的更多相关文章
- BZOJ 1767] [Ceoi2009] harbingers (斜率优化)
[BZOJ 1767] [Ceoi2009] harbingers (斜率优化) 题面 给定一颗树,树中每个结点有一个邮递员,每个邮递员要沿着唯一的路径走向capital(1号结点),每到一个城市他可 ...
- bzoj1767[Ceoi2009]harbingers 斜率优化dp
1767: [Ceoi2009]harbingers Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 421 Solved: 112[Submit][S ...
- 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)
有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...
- Lost My Music:倍增实现可持久化单调栈维护凸包
题目就是求树上每个节点的所有祖先中(ci-cj)/(dj-di)的最小值. 那么就是(ci-cj)/(di-dj)的最大值了. 对于每一个点,它的(ci,di)都是二维坐标系里的一个点 要求的就是祖先 ...
- bzoj3672: [Noi2014]购票(树形DP+斜率优化+可持久化凸包)
这题的加强版,多了一个$l_i$的限制,少了一个$p_i$的单调性,难了好多... 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ $\frac {f(j) ...
- POJ 1180 斜率优化DP(单调队列)
Batch Scheduling Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4347 Accepted: 1992 ...
- Dp优化之决策单调栈优化
证明:g(i) ≤ g(j) (i ≤ j) 令 d=g(i) , k<d , 设cut = x表示 f(i) = f(x) + w[x,i] ( x < i ) 构造一个式子: ...
- Codeforces 1383E - Strange Operation(线段树优化 DP or 单调栈+DP)
Codeforces 题目传送门 & 洛谷题目传送门 Yet another 自己搞出来的难度 \(\ge 2800\) 的题 介绍一个奇奇怪怪的 \(n\log n\) 的做法.首先特判掉字 ...
- ●BZOJ 1767 [Ceoi2009]harbingers
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1767 题解: 斜率优化DP,单调栈,二分 定义 DP[i] 表示从 i 节点出发,到达根所花 ...
随机推荐
- [VUE ERROR] Error in render: "TypeError: Cannot create property 'header' on boolean 'true'"
项目基于ElemnetUi进行的开发,在引入第三方扩展库 vue-element-extends 之后使用它的表格组件报了这个错 解决方案: 1. 删除项目中的 node_modules 2. 删除 ...
- 转发:tomcat的acess_log打印post请求参数,分析日志
转载自:https://blog.csdn.net/qq_30121245/article/details/52861935 1) 在项目中加入相应的包和类,加载那里无所谓,只要web.xml配置正确 ...
- 我的Java之旅 第四课 JAVA 语言语法 基础
1 整型 int num = 1_000_000; //从java 7开始支持的语法 ,只是让人更易读,java编绎器会去除 2 字符串 一定不能使用==运算 ...
- 安卓开发_WebView设置打开网页缩放问题
之前实现打开网页的方式,测试后,发现不能够对网页进行缩放操作,这对部分网页来说是十分不便的, 百度了一下解决方案 其实只需要加几行代码就可以实现网页缩放操作 settings.setUseWideVi ...
- C#微信公众号开发——获取access_token
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.正常情况下access_token有效期为7200秒(两个小时),微信获取access_token接 ...
- 阵列卡raid H730写策略write-through和write-back配置说明
问题描述: 最近公司新进了测试服务器,但是在做阵列的时候忘记写策略里面的配置意思了 就网上查了一下,然后顺便做个笔记记录一下 write-through 数据在写入存储的同时,要写入缓存,这种方式安全 ...
- Unity琐碎(1) 编辑器参数修改
今天在写编辑器面板的时候,突然发现如果面板参数变化的时候,不能实时修改表现效果(参数没有生效). public int monsterCount ; void Awake() { monsterCou ...
- 三叔学FPGA系列之二:Cyclone V中的POR、配置、初始化,以及复位
对于FPGA内部的复位,之前一直比较迷,这两天仔细研究官方数据手册,解开了心中的诸多疑惑,感觉自己又进步了呢..... 原创不易,转载请转原文,注明出处,谢谢. 一.关于POR(Power-On ...
- 17秋 软件工程 团队第五次作业 Alpha Scrum6
17秋 软件工程 团队第五次作业 Alpha Scrum6 今日完成的任务 世强:APP内通知消息发送; 港晨:APP前端登陆界面编写: 树民:Web后端数据库访问模块代码实现: 伟航:Web后端Re ...
- C#异步编程の-------异步编程模型(APM)
术语解释: APM 异步编程模型, Asynchronous Programming Model EAP 基于事件的异步编程模式, Event ...