专栏文章
题解:AT_agc049_e [AGC049E] Increment Decrement
AT_agc049_e题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mioqbhkn
- 此快照首次捕获于
- 2025/12/02 23:24 3 个月前
- 此快照最后确认于
- 2025/12/02 23:24 3 个月前
铜牌题。
这个题目需要一个基本结论:通过 操作完成一个序列的代价是 。
我们可以钦定先做区间、再做单点修改。
那我们考虑先对一个序列做 dp,不妨把状态想得暴力一点,设 为当前计算了前 个位置,第 个位置在区间操作之后为 。
那么转移方程就是 。
然后我们这个地方要用 slope trick 优化了。我之前没有学过这个,所以现在学一下。
学完了。我们考虑分步进行这个转移的过程,首先进行 。
考虑对于 的情况,实际上只需要考虑左半边(单调递减),发现可以全部推平为最小值;
对于 的情况,我们考虑什么时候可以更新,首先显然是只有右半边需要考虑。可以先把所有 置为 ,然后考虑要满足 ,整理一下就是 ,这个可以用函数 来表示, 实质上就是原函数所有的直线斜率减少 ,而不等式的意义是 。考虑不等式满足的条件,发现新的零点就是原来斜率为 的直线的右端点,因此可以用这个零点去更新斜率 的位置,即全部推平。至于为什么不能使用新零点左边的点来更新的原因是,我们发现左侧斜率 ,而附加代价的变化率就是 了,因此向左一定不优。
然后对于 的贡献的维护就是老生常谈了,往维护的容器里塞两个 即可。
我们注意到,根据更新操作的特点,实际上斜率总是 。那我们考虑使用 multiset 维护斜率集合,操作可以如下刻画:
-
预处理:加入 个 ,这是因为 ,即斜率均为 。
-
对于每一轮操作,删去最大值和最小值,这是推平 和 的段。
-
加入两个 。这是加入一个绝对值函数,表示 处的斜率变化值为 。
-
计算贡献,考虑最小值的变化,也是很套路地统计原来最小值的位置和 的最小距离,设原来斜率为 的右端点为 ,它在更新后斜率变为 ,因此贡献要加上 。显然, 也是 multiset 里的最小值。
现在,我们可以 地解决这个子问题了。
考虑整个流程,即加入 个 之后要循环做的事情:
删去最大值和最小值,加入两个 ,。
考虑拆开做,首先计算 部分的贡献系数。由于选了 之后可以随便选,都能产生贡献,因此贡献系数为 。
考虑统计所有情况下的 之和。这里就需要一些 trick 了,首先考虑从值域出发,枚举所有可能的 ,计算最小值 和 的方案数的差值,就是 的贡献系数。这样,就把统计的单点问题转化成区间问题了,而我们也就不关心最大值的情况了。
那我们考虑将问题进一步简化为 问题,这样的好处是将 multiset 的维护转化成了单个变量( 的个数)的维护问题了。不妨让 ,这样相当于如果有 ,那么最小值 成立。
考虑何种情况下最小值不为 。发现每次删除最小值时都会删掉一个最初加上的 (第一轮会删掉两个),因此 轮之后如果此前全都有 ,那么在第 轮时如果 那么本轮会出现一次这样的情况。也就是说,当出现 个 时才能满足条件。此后如果一直满足 那么 的数量就会维持在 (全部为 ),于是可以据此 dp。
设 为前 个位置, 的数量为 ,那么最小值为 的方案数就是 ;可以容斥一下,总方案数是 ,即每个位置都有 种情况产生或者不产生贡献,这样两个值相减就得到了所有位置满足最小值 的方案数之和 。
现在考虑如何转移。考虑当前的 向后进行第 轮的转移,先删去最大值和最小值,即 。
然后枚举可选的 种 ,注意它们本质的不同只在于与 的关系,即有多少个当前能作为 ,剩下的作为 。
这样,我们 dp 的复杂度就是 ,这也是总时间复杂度。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...