【较难题目题解】2025牛客寒假算法基础集训营1

C - 兢兢业业之移

这道题首先需要注意到,那么考虑暴力方法复杂度是否可行:

对于左上角区域的每一个位置,遍历每个位置的时间复杂度,然后对于每一个位置,bfs搜索到一个矩阵中距离最近的“1”,记录下搜索的路径,这样做可以确保该路径上只有“0”,反过来将这个“1”移到中即可,记录每一步的操作,待会输出方案。最差时间复杂度。总共时间复杂度,常数很小,因此可以接受。

下面说明这样做的操作次数。一共有个元素,由于使用bfs搜索路径,每一个元素的移动距离均,因此总操作次数

E - 双生双宿之错

考虑这样一个问题:

对于一个序列a,可以执行以下操作任意次:

将某个元素的值+1或-1。

求使得所有元素相同的最小操作次数。

可以证明,取到最小操作次数时,存在一种解,是将所有的元素变为原始序列a的中位数

如:序列[1, 2, 4, 5, 8],其中位数为4,则将所有的元素变为4,操作次数最小,最小为3+1+0+1+3=8。 当序列为偶数时,存在两个中位数,则选择任意一个中位数,或是两个中位数中间的某个数,操作次数取到最小。

有了这个结论,答案就呼之欲出了:

首先将数组排序,根据“双生数组”的性质,两个元素的个数需相同,那么可以从处将数组分为两部分,前半部分和后半部分分别求变成中位数的最小操作次数即为答案

但这样做还不够:可能存在两部分的中位数相同的情况。设两部分中位数为,在这种情况下,我们分两种情况讨论:

  • 将数组前半部分所有元素变为a-1;
  • 将数组后半部分所有元素变为a+1;

二者取最小值即可。

F - 双生双宿之探

乍一看非常困难的问题。

看到子数组计数问题应该想到使用map。关键是如何将原数组转变为可以计数的数字。

回忆“双生数组”定义,我们可以发现,如果一个数组已经包含超过2个元素,那么它必不可能成为“双生数组”,因此完全不用考虑超过2个元素的数组。

这样一想我们引申出了一条思路:使用一个“队列”,将元素一一放进去,当队列中出现3个不同的元素时,从队头弹出元素,直到队列中只剩两个相同的元素。这样我们就只用考虑统计位于队列中的元素了。

这样队列中就转变为:一个只含有2个元素的数组,求其中“双生子数组”的数量。那么这里可以想到使用map:将某一个元素设为1,另一个元素设为-1,在遍历的过程中使用map记录每一个前缀和。

设当前前缀和为sum,则每次更新map和答案:

ans += map[sum]
map[sum]++;

按照上述思路实现代码即可。时间复杂度

I - 井然有序之桠

这题赛时没时间写了,感觉官方题解说的就非常清楚,这里就不阐述自己的思路了。

K - 硝基甲苯之魇

这道题是最有说法的一题。

首先需要明确一点:一个数组的不同前后缀gcd个数不超过。这个我就不详细证明了,大概意思就是每次gcd要么不变,要么至少是除以2。因此最多只有log个。

因此,在遍历数组时,我们直接就可以记录下来每一个gcd(比如用一个set存起来),然后同时记录下来取到这个gcd所对应的区间起始位置。例如,数组[5, 6, 8, 2, 4, 2],当遍历到时,后缀gcd共有3个:1, 2, 4。其中:

  • gcd=1的最长后缀是[5, 6, 8, 2, 4]
  • gcd=2的最长后缀是[6, 8, 2, 4]
  • gcd=4的最长后缀是[4]。

对于每一个后缀gcd,我们可以使用一个map记录该后缀gcd所对应的前缀异或和的个数。例如,在上面的例子中,gcd=2的map中应该存储了如下的异或和:

  • 5
  • 5^6=3
  • 5^6^8=11
  • 5^6^8^2=9

因此gcd=2对应的map中存储的应该有:

  • 5: 1(1代表有1个前缀异或和=5)
  • 3: 1
  • 11: 1
  • 9: 1

然后,当遍历到下一个元素时,首先需要迭代一次所有存储的gcd值,例如刚才的数组[5, 6, 8, 2, 4, 2],当时,原本gcd可以取1, 2, 4,显然当时gcd就只能取1, 2了。因此遍历到6时,就应该将原本gcd=4的map合并到gcd=2的map中,也就是两个map的元素合并到一起。我们来看看这个合并过程:

原始gcd=2的map有如下信息:

  • 5: 1
  • 3: 1
  • 11: 1
  • 9: 1

gcd=4的map有如下信息:

  • 13: 1

那么合并后,gcd=2的信息应该变为:

  • 5: 1
  • 3: 1
  • 11: 1
  • 9: 1
  • 13: 1

然后再查询每个gcd所对应的区间内,是否有异或和=gcd的集合即可。这里使用刚才的存储前缀异或和的map即可实现。

这个合并的过程,如果暴力合并,总时间复杂度可能会到达,原因是可能会把的集合重复合并n次。

这里我们就可以使用启发式合并对这个集合合并过程进行优化。小集合合并到大集合,将时间复杂度优化至,总时间复杂度约为,可以通过本题。

L - 一念神魔之耀

这题首先看到(以下的n均为题目中的l),考虑的方法都可以通过,那么果断尝试异或高斯消元。

为什么会想到高斯消元?首先,只有2种操作,且每种操作只有种方式,准确来说,对于一个长度为n的序列,如果一次操作可以翻转长度为x的序列,那么它一共就只有种操作形式,这个应该很好理解。

还有一个经典性质:每种操作要么操作0次,要么操作1次。操作偶数次和操作0次是一样的,操作奇数次和操作1次是一样的。

接下来我们就得到了一个n行,列的异或矩阵,使用异或高斯消元求解这个异或方程组即可得到答案。时间复杂度,如果用bitset实现可以做到