关于CF-2276C的思路和题解
题目大意
给定数组长度 n 和整数 k,统计满足两个条件的子数组数目:
- 子数组的和对 k 取模等于 0;
- 子数组长度至少为 k+1。
解题思路
核心是前缀和 + 同余性质 + 二分查找。
区间 [l,r] 的和可以用前缀和表示:sum = s [r] - s [l-1]。
若 sum mod k = 0,等价于 s[r] mod k = s[l-1] mod k。
同时要求子数组长度 ≥ k+1,转换成下标条件:r - (l-1) ≥ k+1。
也就是:找到一对下标 pos 和 r,前缀和模 k 的余数相同,并且两个下标差值大于等于 k+1。
我的实现步骤:
- 多组测试用例循环处理。
- 遍历数组,一边累加得到前缀和,一边计算前缀和模 k 的余数。
- 使用 map,key 存储余数,value 是 vector,保存所有拥有该余数的下标。因为顺序遍历数组,vector 里面的下标天然是升序排列。
- 在遍历数组的时候,额外判断:如果当前前缀和模 k 等于 0,且下标满足长度条件,先计入答案。
- 当数组长度小于 k+1,直接输出 0,不可能存在合法子数组。
- 遍历 map 里每一组余数对应的下标列表。对于列表中每一个下标,利用 lower_bound 二分查找第一个大于等于
当前下标 + k + 1的位置。该位置往后所有元素,都可以和当前下标组成合法下标对,数量累加到答案。 - 最后输出统计好的答案。
思路关键点
- 同余转化:子数组和模 k 为 0 → 两个前缀和余数相等。
- 有序数组二分:同一个余数下标的数组递增,二分快速统计满足下标距离条件的配对数量。
- 提前特判:数组太短直接输出 0,减少无效计算。
代码如下:
![image]()

浙公网安备 33010602011771号