可持久化动态背包问题

题目

题目描述
n n n 种物品,第 i i i 种物品第一次选择的收益是 a i a_i ai,之后每次选择的收益都是 b i b_i bi,代价始终为 c i c_i ci 。你需要求出在总代价不超过 m m m 下收益的最大值。

q q q 次修改,第 j j j 次修改会在第 i    ( i < j ) i\;(i<j) i(i<j) 次修改的基础上修改一个物品的两类收益。你需要对于每次修改后输出答案。

数据范围与提示
n , m , q ⩽ 2000 n,m,q\leqslant 2000 n,m,q2000

思路

这个 “基于第 i i i 次修改后的版本” 很能误导人,让人联想可持久化数据结构。

事实上,可以把所有版本 建成树形关系,子节点是父节点的基础上进行的修改。

此时,一个物品会在一个子树内出现。在这个子树内,如果又被更改,就会消失。所以,每个物品的出现区间是 d f n \rm dfn dfn 的连续区间,并且会挖掉一些 d f n \rm dfn dfn 区间,最终得到的还是多段区间。

究竟有多少段呢?又怎么求呢?其实,直接把每个 “状态更改点” 存下来(类似扫描线,也类似括号匹配)就可以找到出现的区间了。状态更改点一共 4 ( q − 1 ) 4(q-1) 4(q1) 个(更改带来了一组消除和一组加入)。

然后背包问题怎么做?线段树分治 即可。复杂度 O [ ( n + q log ⁡ q ) m ] \mathcal O[(n+q\log q)m] O[(n+qlogq)m]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值