代码源挑战赛 Round 44 题解 - 代码源竞赛平台

T1

100%

我们知道 365≡1(mod7)365 \equiv 1 \pmod 7。 这意味着每过一年,同一日期的星期数会向后推移 11 天(例如从星期四变成星期五)。 反过来看,要保持“星期五”这个属性,日期就需要向前推移 11 天(例如从 22 号变成 11 号)。 在模 77 意义下,日期减 11 等价于加 66。

因此,设 nn 年的第一个星期五的日期为 dnd_n,则有递推公式:

$$d_n \equiv (d_{2026} + (n - 2026) \times 6) \pmod 7$$

其中 d2026=2d_{2026} = 2。

注意计算时负数的情况。

T2

100%

这是一道贪心模拟题。

我们需要维护一个变量 nownow 表示当前积压的任务数量。初始为 00。 从第 11 天遍历到第 nn 天:

  1. 接任务:nownow 加上当天下发的任务数 aia_i。
  2. 做任务:当天能处理的任务数是 min⁡(now,x)\min (now , x )。
  3. 更新 nownow:nownow 减去 min⁡(now,x)\min(now ,x)。

循环结束后,nownow 即为第 nn 天结束时剩余的任务总量。

时间复杂度 O(n)O(n)。

T3

40%

对于每次询问,暴力遍历区间 [l,r][l, r],计算周长。 周长由以下几部分组成:

  1. 底部长度:r−l+1r - l + 1。
  2. 顶部水平长度总和:r−l+1r - l + 1(因为矩形宽度均为 1)。
  3. 左右外侧边:ala_l 和 ara_r。
  4. 内部及顶部垂直边:相邻矩形的高度差绝对值之和,即 ∑i=l+1r∣ai−ai−1∣ \sum_{i=l + 1}^{r} |a_i - a_{i-1}|。

总公式为:$2 \times (r - l + 1) + a_l + a_r + \sum_{i=l + 1}^{r} |a_i - a_{i-1}|$。

暴力计算的时间复杂度为 O(n⋅q)O(n \cdot q)。

100%

观察上述公式,瓶颈在于计算区间相邻项差值的绝对值之和 ∑i=l+1r∣ai−ai−1∣\sum_{i=l + 1}^{r} |a_i - a_{i-1}|。 这可以通过前缀和进行优化。

定义数组 bb,其中 bi=∣ai−ai−1∣b_i =|a_i - a_{i-1}| (对于 2≤i≤n2 \le i \leq n)。

构造 bb 的前缀和数组 SS,其中 Sk=∑j=1kbjS_k = \sum_{j=1}^{k} b_j。

那么 ∑i=l+1r∣ai−ai−1∣\sum_{i=l + 1}^{r} |a_i - a_{i-1}| 就可以用 Sr−SlS_{r} - S_{l} 在 O(1)O(1) 时间内求出。

特别注意当 l=rl=r 时,求和部分为 00。

预处理时间 O(n)O(n),查询时间 O(1)O(1),总时间复杂度 O(n+q)O(n + q)。

T4

100%

设 prepre 是构造出来的数组的前缀异或和。

先考虑 ti=0t_i = 0,如果 ti=0t_i = 0,那么要获胜的条件就是 prel−1 xor prer=0pre_{l - 1} \text{ xor } pre_r = 0。

为什么?

假设第一个人的分数是 s1s_1 ,第二个人的分数是 s2s_2,那么要获胜的条件就是 s1=s2s_1 = s_2,也就是 s1 xor s2=0s_1 \text{ xor } s_2 = 0。

同时 s1 xor s2s_1 \text{ xor } s_2 也是$a_l \text{ xor } a_{l + 1} \text{ xor } a_{l +2} \cdots a_r = pre_{l - 1} \text{ xor } pre_r$ 的值,故 prel−1 xor prerpre_{l - 1} \text{ xor } pre_r 也得是 00。

我们考虑一个 n+1n + 1 个节点的图(编号从 00 到 nn),如果 ti=0t_i = 0,那么就让 l−1l - 1 和 rr 之间连一条无向边,表示 prel−1=prerpre_{l - 1} = pre_{r}。

这时我们考虑将这个图进行染色(染色的值就表示 prepre 的值),其中每个连通块染的颜色都相同。

这个时候再考虑剩下的条件,剩下 ti=1t_i = 1 的限制我们可以尽量满足,也就是让图中的不同联通块的值都不一样,此时再检查所有 ti=1t_i = 1 的限制,看看是否满足,不满足则输出 −1-1。

以及最后一个 ai≠0a_i \not = 0 的条件,等价于 i i+1 1,记得处理即可。

此时我们得到了前缀异或值,只要将其转换为原来的 aa 数组即可。

时间复杂度 O(n+q)O(n+q)。

T5

100%

利用二进制分解的思想构造。

我们考虑构造出一些点 v0,v1,v2,⋯ ,v29v_0, v_1 ,v_2 ,\cdots, v_{29}(vi≠1v_i \not= 1 且 vi≠nv_i \not= n),其中 viv_i 到 nn 的路径数量为 2i2^i。如果我们构造出了这些点,接下来只要根据 KK 的二进制表示来进行连边,就能得到答案。(如果 KK 的第 ii 位是 11,就将 11 向 viv_i 连一条边)

先考虑 v0v_0 的构造,我们只需要将 v0v_0 直接连向 nn 即可。

假设我们已经完成了 v0,v1,v2,⋯vi−1v_0 , v_1 ,v_2, \cdots v_{i -1},如何构造出 viv_i 呢?

我们可以让 viv_i 分别向 v0,v1,v2,⋯vi−1v_0 , v_1 ,v_2 ,\cdots v_{i -1} 连一条边,再向 nn 连一条边即可。

此时 viv_i 到 nn 的方案数为 20+21+22+⋯2i−1+1=2i2^0 + 2^1 + 2^2 + \cdots 2^{i - 1} + 1 = 2^i,满足条件。

T6

100%

首先,我们可以除去每个数 aia_i 中所有的平方因子,只保留“无平方因子部分”。 例如:12=22×3→312 = 2^2 \times 3 \to 3,8=22×2→28 = 2^2 \times 2 \to 2,44=22×11→1144 = 2^2 \times 11 \to 11。

此时 aia_i 和 aja_j 如果满足条件,则变成了: ai=aj×pa_i = a_j \times p, 或者 v=u×pv = u \times p。其中 pp 是任意质数。

考虑莫队,同时维护出以下两个数组:

  1. cnt[x]cnt[x]:表示数值 xx 在当前区间内出现的次数。
  2. f[y]f[y]:辅助数组。由于我们要找的是 x=y×px = y \times p 的关系,f[y]f[y] 表示当前区间内有多少个大数 ZZ,满足 ZZ 去掉一个质因子后等于 yy(即 ZZ 是 yy 的质数倍)。

现在考虑插入一个数 xx 时,对答案的贡献:

  1. xx 作为大数时,我们考虑枚举其所有的质因子 pp,其中 (xp,x)(\frac{x}{p}, x) 的贡献为 cnt[xp]cnt[\frac{x}{p}]。
  2. xx 作为小数时,贡献为 f[x]f[x]。

最后记得更新 f[xp]f[\frac{x}{p}] 的值。

删除数的想法类似,这里不再赘述。

时间复杂度为 O(nnlog⁡log⁡n)O(n\sqrt{n} \log\log n)。