- 代码源挑战赛 Round 64
代码源挑战赛 Round 64 题解
- @ 2026-6-6 17:22:08
A
100%
的十进制表示就是一个 1,后面接 个 0。
由于 ,结果可能超过普通整数范围,直接按字符串输出即可。
时间复杂度 。
B
100%
按照题意统计所有被射中的格子的分数总和即可。
先读入分数矩阵 ,再读入字符矩阵。对于每个位置 :
- 如果字符为
X,则把 加入答案; - 如果字符为
.,则跳过。
注意 ,且 ,总分最大可能达到 级别,需要用 long long。
时间复杂度 ,空间复杂度 。
C
40%
设 表示第 盆盆栽在最近一次处理后的水分;
由于操作都是按照时间升序的,故我们考虑 具体要做什么。
在 的过程中,我们需要更新每一盆盆栽的含水量,具体为
这样查询的时候只需要输出 即可。
时间复杂度 。
100%
观察到每盆盆栽之间互不影响,因此可以对每一盆单独维护它最近一次被处理后的状态。
设:
- 表示第 盆盆栽在最近一次处理后的水分;
- 表示第 盆盆栽最近一次被处理的时刻。
初始时 。
当时刻 发生关于第 盆盆栽的事件时,先结算从 到 的自然蒸发:
然后令:
接下来根据事件类型处理:
- 若为
1 t x v,则浇水后令 ; - 若为
2 t x,则当前答案就是 。
虽然所有事件的时间整体递增,但同一盆盆栽不一定每次都会出现,所以不能只维护一个全局时间,必须为每盆盆栽分别记录 。
水分经过多次浇水后可能达到 级别,需要用到 long long。
时间复杂度 ,空间复杂度 。
D
100%
整条街区的黑暗程度只由相邻点亮路灯之间的间隔决定。
当切换位置 时,除了 附近的前驱 和后继 之外,其它点亮路灯之间的相邻关系不会变化,因此它们的贡献也不会变化。
故只需要维护当前所有点亮路灯的位置集合,以及相邻点亮路灯之间的贡献和。
设:
表示点亮位置 和 相邻时,它们之间这一段对答案的贡献。
用一个 set 维护当前点亮的位置,另用变量 维护当前黑暗程度。
插入一个位置
如果当前要把熄灭的 点亮,设 set 中:
- 为小于 的最大点亮位置;
- 为大于 的最小点亮位置。
插入 之前,如果 和 都存在,那么 原本相邻,需要先减去 。
插入 之后,新的相邻关系变为 和 ,所以:
- 如果 存在,则加上 ;
- 如果 存在,则加上 。
最后把 插入 set。
删除一个位置
如果当前要把点亮的 熄灭,同样找到它的前驱 和后继 。
删除 前,相邻关系中可能包含 和 ,所以:
- 如果 存在,则减去 ;
- 如果 存在,则减去 。
删除 后,如果 和 都存在,它们会变成新的相邻点亮路灯,需要加上
最后把 从 set 中删除。
每次操作结束后输出 即可。若当前点亮路灯少于 盏,上述维护方式自然会得到 。
答案最大约为 ,需要使用 long long。
其中 和 可以利用 set 的 lower_bound/upper_bound 来快速找出。
时间复杂度 。
E
100%
若 ,只需要统计单个数字本身是 的倍数的位置数量,也就是字符为 0、4、8 的数量。
下面考虑 的情况。
可以观察到一个十进制整数是否为 的倍数,只与最后两位有关。以下是具体证明:
设一个长度至少为 的十进制整数为:
其中 分别是倒数第二位和最后一位。由于 是 的倍数,所以:
因此:
也就是说,百位及更高位无论如何选择,都不会影响这个数是否为 的倍数。于是对于 的子序列,只需要判断最后两位组成的两位数是否为 的倍数。
枚举子序列的倒数第二位位置 。
设 对应的数字为 。如果最后一位数字为 ,那么最后两位组成的数为:
它需要满足:
为了快速统计这样的最后一位,可以从右往左扫描字符串,并维护 ,其中 表示当前位置右侧数字 出现了多少次。
当扫描到位置 时,枚举最后一位数字 。如果 是 的倍数,那么右侧任意一个数字为 的位置都可以作为最后一位。
此时最后两位位置已经确定为 。为了让它们成为整个长度为 的子序列的最后两位,前面的 个位置必须从 中选择,方案数为:
所以这一类贡献为:
把所有满足条件的 的贡献加入答案后,再令:
表示当前位置也可以作为更左侧位置的最后一位。
所有组合数都对 取模,可以预处理阶乘和逆元,在 时间内求出 。当 时组合数视为 。
时间复杂度 ,空间复杂度 。
F
100%
直接模拟每个人从 走到 会超时。
可以发现关键是快速找到“当前钱数买得起的、还没被买走的最靠左商品”。
维护一棵线段树。线段树的每个叶子表示一个商铺:
- 若该商品还没有被买走,叶子值为它的价格 ;
- 若该商品已经被买走,叶子值为 。
每个区间节点维护该区间内剩余商品价格的最小值。
对于第 个人,设他当前手里的钱为 。
我们的目标是在线段树上全局查询最小的下标 ,满足该位置还未被买走且 。
如果不存在这样的 ,说明当前已经没有买得起的商品,这个人购物结束。
如果找到了 ,那么这个人一定会买下第 个商品。
买下后做
并在线段树中把位置 更新为 ,表示该商品已经下架。然后继续查询下一件商品。
线段树查询方式
查询整棵线段树中第一个价格不超过 的位置。可以考虑线段树上二分,即从线段树的根出发。
具体查询时:
- 如果根节点的最小值大于 ,说明当前没有任何可以买的商品;
- 否则从根节点开始向下走。设当前节点的左右儿子分别为 ;
- 如果 维护的最小值不超过 ,说明左半区间中存在可以买的商品,并且答案一定在左半区间,于是往左儿子走;
- 否则左半区间没有可以买的商品,答案只能在右半区间,于是往右儿子走。
不断重复这个过程直到叶子节点,就能得到全局最小的可购买下标。
由于每次成功购买会删除一个商品,因此所有人成功购买的总次数不超过 。每个人还会进行一次失败查询来结束自己的购物过程。所以线段树查询和修改的总次数为 ,每次复杂度 。总时间复杂度 ,空间复杂度 。