D - お菓子の分配 / Distribution of Sweets 解説 by admin
Claude 4.5 OpusOverview
This problem asks you to efficiently count the number of ways to select contiguous subsequences whose total weight is a multiple of \(K\), using prefix sums and properties of modular arithmetic.
Analysis
Naive Approach
If we consider trying all contiguous subsequences, there are \(O(N^2)\) combinations of starting point \(l\) and ending point \(r\). Furthermore, if we calculate the sum of each subsequence, the overall complexity becomes \(O(N^3)\), or \(O(N^2)\) even with prefix sums, which is too slow for \(N \leq 2 \times 10^5\).
Key Insight: Relationship Between Prefix Sums and Remainders
If we define the prefix sum \(S[i] = A_1 + A_2 + \cdots + A_i\) (with \(S[0] = 0\)), then the sum of the contiguous subsequence \([l+1, r]\) can be expressed as \(S[r] - S[l]\).
The condition for this sum to be a multiple of \(K\) is: $\(S[r] - S[l] \equiv 0 \pmod{K}\)$
Rearranging this gives: $\(S[r] \equiv S[l] \pmod{K}\)$
In other words, if we select two indices whose prefix sums have the same remainder when divided by \(K\), then the sum of the subsequence between them is a multiple of \(K\).
Concrete Example
For \(N = 4, K = 3, A = [1, 2, 3, 6]\):
| \(i\) | \(S[i]\) | \(S[i] \mod 3\) |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 3 | 0 |
| 3 | 6 | 0 |
| 4 | 12 | 0 |
There are 4 indices with remainder 0: \(\{0, 2, 3, 4\}\), so choosing 2 from these contributes \(_4C_2 = 6\) combinations to the answer.
Algorithm
- Calculate the prefix sum \(\mod K\) sequentially
- Use a dictionary (hash map) to track how many times each remainder value has appeared
- When calculating a new prefix sum remainder \(r\), add the number of times the same remainder \(r\) has already appeared to the answer
- Then increment the count of remainder \(r\) by 1
Why does this count correctly?
As we look at each prefix sum \(S[i]\) in order, when \(S[i] \mod K = r\), if there are \(c\) previous prefix sums with the same remainder \(r\), we can pair \(S[i]\) with each of those \(c\) prefix sums. Each pair corresponds to one valid subsequence.
Setting count[0] = 1 in the initial state represents \(S[0] = 0\) (the state of selecting nothing).
Complexity
- Time complexity: \(O(N)\)
- We traverse the array once, performing \(O(1)\) dictionary access for each element
- Space complexity: \(O(\min(N, K))\)
- The number of distinct remainders stored in the dictionary is at most \(\min(N+1, K)\)
Implementation Notes
- Using
defaultdict(int)automatically returns 0 for remainders that haven’t appeared yet - Since \(K\) can be as large as \(10^9\), we need to use a dictionary instead of an array (an array would run out of memory)
- We only need to keep the remainder of the prefix sum divided by \(K\); there’s no need to store the prefix sums themselves in an array
- Be careful not to forget the initialization
count[0] = 1, or you’ll miss counting subsequences that start from the beginning
Source Code
from collections import defaultdict
def solve():
N, K = map(int, input().split())
A = list(map(int, input().split()))
# Calculate prefix sum mod K
# S[i] = (A[0] + A[1] + ... + A[i-1]) mod K
# Sum of contiguous subsequence [l, r) is a multiple of K ⇔ S[r] ≡ S[l] (mod K)
# Count occurrences of each prefix sum mod K
count = defaultdict(int)
count[0] = 1 # Empty prefix sum (before index 0)
prefix_sum_mod = 0
result = 0
for i in range(N):
prefix_sum_mod = (prefix_sum_mod + A[i]) % K
# Add the count of previous prefix sums with the same mod K
result += count[prefix_sum_mod]
count[prefix_sum_mod] += 1
print(result)
solve()
This editorial was generated by claude4.5opus.
投稿日時:
最終更新: