2020CCPC长春 The Tortoise and the Hare (树套树 / 整体二分)

题目链接: The Tortoise and the Hare

大致题意

题目背景大概是说龟兔赛跑的事情.

龟兔赛跑的总路程为m, 有n个乌龟, 当兔子跑到终点的时候第i个乌龟已经跑了ai. 接下来有d天, 每天有两种事件.

​ 事件一: 兔子拉着[l, r]区间内的乌龟去赛跑, 当他即将跑到终点后, 他会睡觉, 每一时刻他可以使得k个乌龟停留在原地, 剩下的乌龟会前进1. 兔子最终希望赢得比赛, 问最多能睡多久.

​ 事件二: ai会变化为c.

解题思路

考虑到事件一, 我们发现, 如果可以睡觉的时间t, 则距离终点超过t(即: ai + t < m)的乌龟是不需要被施咒的, 反之则需要被施咒, 次数应为ai + t - m + 1.

我们考虑二分求解. 每次假设有num个乌龟不满足要求, 这些乌龟距离终点可走的总距离为sum, 则需要满足比下述等式: t * num - min(k, num) * t <= sum

这里解释一下什么叫 距离终点可走的距离, 如果兔子此时到了终点, 乌龟走了ai, 则距离终点为 m - ai, 距离终点可走距离为 m - ai - 1.

那么对于答案的值域而言, 一定存在一个res, 使得其左半部分(包括res), 都满足兔子胜利这一条件, 而右半部分均不满足. 因此我们相当于需要二分尽可能靠右的答案

在这里插入图片描述

而事件二就相当于一个单点修改操作, 我们只需要考虑如何来维护a数组即可.

思路一: 区间线段树套平衡树

考虑到事件一, 我们可以在树外进行二分, 然后在区间线段树中找到[l, r], 在平衡树中查询符合条件的sum和num.

需要注意的是, 这样嵌套 + 树外二分的方式常数很大. 平衡树不推荐用splay, 的确卡常. 但是最后还是脑抽想了几个优化把题目刚过去了 6000ms我跑了5900多. 感谢评测机Orz🙏.

AC代码在这里➡️ 树套树AC代码

思路二: 整体二分

这里虽然思路二写的是整体二分, 主要考虑到有大佬已经出过整体二分的解法了Orz. 但是对于本题而言, 力推整体二分! 题目中一共只有两个操作, 且询问操作还满足二分的性质, 所以我们可以直接整体二分值域求解.

对于查询操作, 我们每次假设当前mid为答案, 如果发现此时mid可以被满足, 则记录上[l, mid]区间的贡献, 然后递归到右半区间处理. 若不被满足, 则直接递归到左半区间处理.

协助维护的数据结构可以用线段树, 也可以采用树状数组, 如果采用树状数组, 需要开两个分别维护num与sum.

时间复杂度: O(nlog值域logn)
空间复杂度: O(n)

AC代码在这里➡️ 整体二分AC代码

AC代码请点击对应思路链接下的查看


说点题外的, 对于树套树的做法.

其实最开始我也写过线段树套线段树, 可是无论你怎么套, 空间上nlognlogn是无法承受的. 所以只能来套平衡树.

我看官方题解是权值线段树套区间平衡树. 感觉自己的想法可能有点固化, 总感觉外层开权值树反而不好写, 所以一直就没有尝试. 但是这个题也的确花费了我们多的经历去思考树套树, 错了很多次, 但是也提升了很多. 总之! 现在整体二分和树套树的做法我都写出来了, 不太想再碰这个题了.

希望本文能够帮到您. 如果您发现了本文中的错误, 也欢迎评论区指出.

END

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍遥Fau

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值