我们考虑右端点在i位置的话,符合条件的区间的左端点j在哪里?如果我们将区间和转化为前缀和来看,sum[i:j]能被K整除的充要条件就是:presum[i]和presum[j-1]除以K的余数相同。于是我们用计数器记录i之前presum对K除的余数各自出现了多少次。如果presum[i]%K=r
,那么count[r]就意味着有多少个位置j能配对成符合条件的区间。
注意前缀和可能是负数,而C++中整除的余数允许是负数。所以我们在计算余数的时候需要转化为 (presum % k + k) % k
。