BZOJ3672: [Noi2014]购票(dp 斜率优化 点分治 二分 凸包)
题意
Sol
介绍一种神奇的点分治的做法
啥?这都有根树了怎么点分治??
嘿嘿,这道题的点分治不同于一般的点分治。正常的点分治思路大概是先统计过重心的,再递归下去
实际上一般的点分治与统计顺序关系不大,也就是说我可以先统计再递归,或者先递归再统计。
但是这题不单单是统计,它是dp,存在决策顺序问题,我们就需要换一种思路了。
首先我们可以这样考虑:对于每个点\(x\),找出子树重心\(root\),对除去重心外的部分递归执行该操作,那么回溯回来的时候,我们默认除重心的子树外答案都已经更新好了。
接下来考虑重心子树内的点的转移,我们只需要考虑从\(root\)到\(x\)的路径,显然排序之后双指针可以做到\(nlogn\)的复杂度。(对转移位置按深度排序,对要更新的点按深度 - 限制长度排序,双指针的时候维护一下凸包,因为\(p\)不单调所以需要在凸包上二分)
复杂度不太会严格的证明,但是跑的飞快。因为虽然我们的分治结构变了,但每次还是找重心更新答案,所以复杂度是有保证的。
#include<bits/stdc++.h>
#define int long long
#define LL long long
using namespace std;
const int MAXN = 1e6 + 10, mod = 1e9 + 7, INF = 3e18 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A> inline void debug(A a){cout << a << '\n';}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, T, fa[MAXN], d[MAXN], pp[MAXN], qq[MAXN], lim[MAXN], siz[MAXN], Sum, vis[MAXN], Mx, root, f[MAXN], st[MAXN], top, cnt;
vector<int> v[MAXN];
void dfs(int x) {
d[x] += d[fa[x]]; siz[x] = 1;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i]; if(to == fa[x]) continue;
dfs(to); siz[x] += siz[to];
}
}
void Find(int x) {
//printf("%d\n", x);
int mx = 0; siz[x] = 1;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i]; if(to == fa[x] || vis[to]) continue;
Find(to); siz[x] += siz[to];
chmax(mx, siz[to]);
}
chmax(mx, Sum - siz[x]);
if(mx < Mx && siz[x] > 1) Mx = mx, root = x;
}
struct Node {
int id, dis;
bool operator < (const Node &rhs) const {
return dis > rhs.dis;
}
}a[MAXN];
void dfs2(int x) {
a[++cnt].id = x;
a[cnt] = (Node) {x, d[x] - lim[x]};
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i]; if(to == fa[x] || vis[to]) continue;
dfs2(to);
}
}
int Y(int x) {
return f[x];
}
int X(int x) {
return d[x];
}
double slope(int x, int y) {
return (double) (Y(y) - Y(x)) / (X(y) - X(x));
}
void insert(int x) {
while(top > 1 && slope(st[top], x) > slope(st[top - 1], st[top])) top--;
st[++top] = x;
}
int Search(double x, int id) {
if(!top) return INF;
int l = 1, r = top - 1, ans = 1;
while(l <= r) {
int mid = l + r >> 1;
if((slope(st[mid], st[mid + 1]) >= x)) ans = mid + 1, l = mid + 1;
else r = mid - 1;
}
return f[st[ans]] - d[st[ans]] * pp[id];
}
void solve(int x, int tot, int up) {
vector<int> pot;
for(int t = x; t != up; t = fa[t])
pot.push_back(t);
cnt = 0;
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i]; if(to == fa[x]) continue;
dfs2(to);//dep´Ó´óµ½´ïС£¬dis´Ó´óµ½Ð¡
}
sort(a + 1, a + cnt + 1);
int now = 0; top = 0;
for(int i = 1; i <= cnt; i++) {
int cur = a[i].id;
while(now <= pot.size() - 1 && d[pot[now]] >= a[i].dis) insert(pot[now++]);
chmin(f[cur], Search(pp[cur], cur) + qq[cur] + d[cur] * pp[cur]);
}
}
void work(int x, int tot) {
if(tot == 1) return ;
root = x; Sum = tot; Mx = Sum; Find(root);
int rt = root;
for(int i = 0; i < v[rt].size(); i++) {
int to = v[rt][i]; if(to == fa[rt]) continue;
vis[to] = 1;
}
work(x, tot - siz[root] + 1);
solve(rt, tot, fa[x]);
for(int i = 0; i < v[rt].size(); i++) {
int to = v[rt][i]; if(to == fa[rt]) continue;
work(to, siz[to]);
}
}
signed main() {
//freopen("a.in", "r", stdin);
N = read(); T = read();
for(int i = 2; i <= N; i++) {
fa[i] = read();
v[fa[i]].push_back(i); v[i].push_back(fa[i]);
d[i] = read(); pp[i] = read(); qq[i] = read(); lim[i] = read();
}
dfs(1);
memset(f, 0x7f7f7f, sizeof(f)); f[1] = 0;
work(1, N);
for(int i = 2; i <= N; i++) cout << f[i] << '\n';
return 0;
}
/*
7 3
1 2 20 0 3
1 5 10 100 5
2 4 10 10 10
2 9 1 100 10
3 5 20 100 10
4 4 20 0 10
*/
BZOJ3672: [Noi2014]购票(dp 斜率优化 点分治 二分 凸包)的更多相关文章
- $NOI2014$ 购票(斜率优化 点分治)
\(NOI2014\)购票 哇终于可以碰电脑了赶快切些火题找找感觉. 拿到这道题的时候发现简单的斜率优化推一推可以秒掉平方做法,然后一条链也可以做. 然后呢... 卧槽这个在一棵树上怎么办啊. 大力\ ...
- 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 3396 Solved: 1434[Submit][Sta ...
- 洛谷.4655.[CEOI2017]Building Bridges(DP 斜率优化 CDQ分治)
LOJ 洛谷 \(f_i=s_{i-1}+h_i^2+\min\{f_j-s_j+h_j^2-2h_i2h_j\}\),显然可以斜率优化. \(f_i-s_{i-1}-h_i^2+2h_ih_j=f_ ...
- BZOJ.1492.[NOI2007]货币兑换(DP 斜率优化 CDQ分治/Splay)
BZOJ 洛谷 如果某天能够赚钱,那么一定会在这天把手上的金券全卖掉.同样如果某天要买,一定会把所有钱花光. 那么令\(f_i\)表示到第\(i\)天所拥有的最多钱数(此时手上没有任何金券),可以选择 ...
- dp斜率优化
算法-dp斜率优化 前置知识: 凸包 斜率优化很玄学,凭空讲怎么也讲不好,所以放例题. [APIO2014]序列分割 [APIO2014]序列分割 给你一个长度为 \(n\) 的序列 \(a_1,a_ ...
- 【BZOJ-4518】征途 DP + 斜率优化
4518: [Sdoi2016]征途 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 230 Solved: 156[Submit][Status][ ...
- 【BZOJ-3437】小P的牧场 DP + 斜率优化
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 705 Solved: 404[Submit][Status][Discuss ...
- 【BZOJ-1010】玩具装箱toy DP + 斜率优化
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8432 Solved: 3338[Submit][St ...
- 【BZOJ】1096: [ZJOI2007]仓库建设(dp+斜率优化)
http://www.lydsy.com/JudgeOnline/problem.php?id=1096 首先得到dp方程(我竟然自己都每推出了QAQ)$$d[i]=min\{d[j]+cost(j+ ...
随机推荐
- 【bzoj4259】 残缺的字符串 FFT
又是一道FFT套路题 思路可以参考bzoj4503,题解 我们对串S和串T中出现的*处全部赋值为0. 反正最终的差异度式子大概就是 $C[i]=\sum_{j=0}^{|T|-1}S[i+j]T[j] ...
- 剑指offer五十九之按之字形顺序打印二叉树
一.题目 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推.二.思路 详见代码 三.代码 import j ...
- Flow中的Switch分析
A switch statement can complete normally iff at least one of the following is true: (1)The switch bl ...
- docker 容器启动后立马退出的解决方法
原因: 容器同时只能管理一个进程,如果这个进程结束了容器就退出了,但是不表示容器只能运行一个进程(其他进程可在后台运行),但是要使容器不退出必须要有一个进程在前台执行. 解决方案: 启动脚本最后一 ...
- ggplot2基础学习
前言 ggplot2是R语言最流行的第三方扩展包,是RStudio首席科学家Hadley Wickham读博期间的作品,是R相比其他语言一个独领风骚的特点.包名中“gg”是grammar of gra ...
- elasticsearch(三) 之 elasticsearch目录介绍和配置文件详解
目录 elasticsearch 配置 目录详情 (config) 配置文件 elasticsearch.yml 配置集群名称(cluster.name) 配置 network.host 更改数据和储 ...
- php通过生成动态变量(变量名中还有变量)
借鉴:http://blog.sina.com.cn/s/blog_7193eeac0100zwld.html 如果想for循环生成变量 如: $a1,$a2,$a3.... $name = &quo ...
- pmm 监控mysql、mongodb、系统
Pmm监控 1.概述 Pmm是(percona management and monitoring)一款用于数据库(mysql.mongodb)的监控工具,是一种典型的C/S架构.本次部署采用的是do ...
- Java中的数据验证
原文链接:https://www.cuba-platform.com/blog/2018-10-09/945 翻译:CUBA China CUBA-Platform 官网 : https://www. ...
- Asp.net MVC中关于@Html标签Label、Editor使用
@Html帮助器简单说明,记录些基本的跟HTML中对应的@html帮助器,@Html基本包含了html中的表单控件和常用Html在@Html中,带有For的主要是针对强类型的Html类型.用于说明@H ...