bzoj3672: [Noi2014]购票(树形DP+斜率优化+可持久化凸包)
这题的加强版,多了一个$l_i$的限制,少了一个$p_i$的单调性,难了好多...
首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$
$\frac {f(j)-f(k)}{dep_j-dep_k}<p_i$
假如没有$l_i$的限制,实际上就是上面那题...
如果多了$l_i$的限制会有什么影响呢?

类似上图的情况...红线是$l_i$的限制,如果是单调队列写法的话,P点会被删掉,但实际上P点依然有可能成为最优决策点...
这个时候一个单调队列的写法就不可行了...
之所以会出现这个问题,是因为P点被不属于$l_i$范围内的点给弹出了,所以我们只能在不存在$l_i$之外的点的单调队列里查,但是这样我们要开$O(n)$个队列,显然无法承受,但是我们知道的是,凸包是可以合并的,所以直接用线段树来维护就好了。
我们需要维护$2n$个队列,像线段树一样,分别维护深度为$[1,dep],[1,dep/2],[dep/2+1,dep],[1,dep/4],[dep/4+1,dep/2],...$的单调队列,每次询问的时候把在距离范围内的区间一个一个合并起来,每个区间都需要二分$O(logn)$找出最优决策点,最后合并$O(logn)$个区间,合并的时候只需要求出一个各个区间最优决策点的凸包就好了,每次合并$O(1)$,复杂度$O(nlog^2n)$。
修改的话同理,把包含当前点的所有区间都二分找到出队位置移动队尾位置,同时记录下被覆盖的点,维护一下可持久化凸包,然后就可以了,这一部分细节比较多,结合代码更好理解。
队列数组开小+很多地方没开LL+困=调了1h,第一次编译的时候代码就没有实质上的错误了,但是却调了那么久,sigh...
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll long long
#define int long long
using namespace std;
const int maxn=, inf=1e9;
struct poi{int too, dis, pre;}e[maxn];
struct tjm{int bg, len;}tree[maxn<<];
int n, m, x, z, tot, sum;
int v[maxn*], last[maxn], p[maxn], l[maxn], memv[maxn][], meml[maxn][];
ll f[maxn], dep[maxn], deep[maxn], q[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-'&&(f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void add(int x, int y, int z){e[++tot]=(poi){y, z, last[x]}; last[x]=tot;}
inline double xl(int x, int y){return 1.0*(f[x]-f[y])/(deep[x]-deep[y]);}
inline int findans(int l, int r, ll limit)
{
if(l>=r) return r;
int L=l+, R=r;
while(L<R)
{
int mid=(L+R)>>;
if(limit-xl(v[mid], v[mid-])>1e-) L=mid+;
else R=mid;
}
if(xl(v[L], v[L-])>=limit) L--;
return L;
}
inline int find(int r, int limit)
{
int L=, R=r;
while(L<R)
{
int mid=(L+R)>>;
if(dep[mid]>=limit) R=mid;
else L=mid+;
}
return L;
}
inline int findr(int l, int r, int pos)
{
if(l>=r) return r;
int L=l+, R=r;
while(L<R)
{
int mid=(L+R+)>>;
if(xl(v[mid], v[mid-])-xl(v[mid], pos)>1e-) R=mid-;
else L=mid;
}
if(xl(v[L], v[L-])-xl(v[L], pos)>1e-) L--;
return L;
}
void build(int x, int l, int r)
{
tree[x].bg=sum; sum+=r-l+;
if(l==r) return;
int mid=(l+r)>>;
build(x<<, l, mid); build(x<<|, mid+, r);
}
int query(int x, int l, int r, int cx, ll limit)
{
if(!tree[x].len || r<cx) return -;
if(cx<=l) return findans(tree[x].bg, tree[x].bg+tree[x].len-, limit);
int mid=(l+r)>>, lt=query(x<<, l, mid, cx, limit), rt=query(x<<|, mid+, r, cx, limit);
if(lt!=- && rt!=-) if(limit-xl(v[lt], v[rt])>1e-) swap(lt, rt);
return lt==-?rt:lt;
}
void update(int x, int l, int r, int cx, int pos, int d)
{
int R=findr(tree[x].bg, tree[x].bg+tree[x].len-, pos);
memv[pos][d]=v[++R]; meml[pos][d]=tree[x].len; v[R]=pos; tree[x].len=R-tree[x].bg+;
if(l==r) return;
int mid=(l+r)>>;
if(cx<=mid) update(x<<, l, mid, cx, pos, d+);
else update(x<<|, mid+, r, cx, pos, d+);
}
void recovey(int x, int l, int r, int cx, int pos, int d)
{
v[tree[x].bg+tree[x].len-]=memv[pos][d]; tree[x].len=meml[pos][d];
if(l==r) return;
int mid=(l+r)>>;
if(cx<=mid) recovey(x<<, l, mid, cx, pos, d+);
else recovey(x<<|, mid+, r, cx, pos, d+);
}
void dfs(int x, int d)
{
if(x!=)
{
int limit=dep[d]-l[x], nxt=v[query(, , n, find(d-, limit), p[x])];
f[x]=f[nxt]+(deep[x]-deep[nxt])*p[x]+q[x];
}
update(, , n, d, x, );
for(int i=last[x], too;i;i=e[i].pre)
deep[too=e[i].too]=deep[x]+e[i].dis, dep[d+]=dep[d]+e[i].dis, dfs(too, d+);
recovey(, , n, d, x, );
}
#undef int
int main()
{
read(n); read(m);
for(int i=;i<=n;i++)
read(x), read(z), read(p[i]), read(q[i]), read(l[i]), add(x, i, z);
sum=; build(, , n); dfs(, );
for(int i=;i<=n;i++) printf("%lld\n", f[i]);
}
bzoj3672: [Noi2014]购票(树形DP+斜率优化+可持久化凸包)的更多相关文章
- 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)
有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...
- BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化
BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参 ...
- [NOI2014]购票 「树上斜率优化」
首先易得方程,且经过变换有 $$\begin{aligned} f_i &= \min\limits_{dist_i - lim_i \le dist_j} \{f_j + (dist_i - ...
- 【BZOJ-3672】购票 树分治 + 斜率优化DP
3672: [Noi2014]购票 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1177 Solved: 562[Submit][Status][ ...
- 【BZOJ3672】[Noi2014]购票 树分治+斜率优化
[BZOJ3672][Noi2014]购票 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- P3994 高速公路 树形DP+斜率优化+二分
$ \color{#0066ff}{ 题目描述 }$ C国拥有一张四通八达的高速公路网树,其中有n个城市,城市之间由一共n-1条高速公路连接.除了首都1号城市,每个城市都有一家本地的客运公司,可以发车 ...
- Codeforces 1179D 树形DP 斜率优化
题意:给你一颗树,你可以在树上添加一条边,问添加一条边之后的简单路径最多有多少条?简单路径是指路径中的点只没有重复. 思路:添加一条边之后,树变成了基环树.容易发现,以基环上的点为根的子树的点中的简单 ...
- 【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 ...
随机推荐
- Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用
Netty源码分析第一章:Netty启动流程 第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...
- Spring入门学习笔记(1)
目录 Spring好处 依赖注入 面向面编程(AOP) Spring Framework Core Container Web Miscellaneous 编写第一个程序 IoC容器 Spring B ...
- 新手Python第一天(接触)
Python 变量 Python的变量由字母,数字,下划线组成不包含特殊字符,不能以数字开头 可以使用的名称 例如:name,name2,my_name 不可使用的名称 例如:if...(Python ...
- Streamr助你掌控自己的数据(2)——三种整合数据至Streamr的典型场景
博客说明 所有刊发内容均可转载但是需要注明出处. 三种整合数据至Streamr的典型场景 本系列文档主要介绍怎么通过Streamr管理自己的DATA,整个系列包括三篇教程文档,分别是:教你5分钟上传数 ...
- CentOS 7 安装图形化界面及 Xshell 连接
CentOS 比较适合用作服务器的系统,之前用过 CentOS 6,但是在配置 Nginx 的时候,发现很多语句版本7的系统都进行了更新,而且网上针对版本7的例子会更多一下,遂将系统换成版本7. 下载 ...
- 后端程序员必备的Linux基础知识
我自己总结的Java学习的系统知识点以及面试问题,目前已经开源,会一直完善下去,欢迎建议和指导欢迎Star: https://github.com/Snailclimb/Java-Guide > ...
- HTTP-HTTPS区别
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...
- Django_rest_framework_组件(authentication、permission、throttle)
认证组件 说明 from rest_framework.authentication import BaseAuthentication class TestAuthentication(BaseAu ...
- centos下部署禅道流程
原文摘录:https://www.jianshu.com/p/71e9dab130a5 下面将我在Linux系统下搭建禅道服务的过程分享给大家. 第一步:下载禅道 Linux中可以用以下命令来下载安装 ...
- Chapter 3 软件项目管理
软件项目具有产品的不可见性.项目的高度不确定性.软件过程的多变化性.软件人员的高流动性的显著特征.有效的软件项目管理集中于人员.产品.过程和项目四个方面.软件项目的生命周期有项目启动.项目规划.项目实 ...