C - お菓子の詰め合わせ / Assortment of Sweets Editorial by admin
Claude 4.6 Opus (Thinking)Overview
This problem asks us to find the number of ways to choose \((l, r)\) such that the total weight of a contiguous subsequence does not exceed the minimum bag capacity \(C_{\min}\). We efficiently count these using the two pointers technique (sliding window).
Analysis
Essence of the Problem
There are \(M\) bag capacities, but the only one that matters is the minimum value \(C_{\min} = \min(C_1, \ldots, C_M)\). Therefore, the problem can be rephrased as follows:
Find the number of pairs \((l, r)\) (\(1 \leq l \leq r \leq N\)) satisfying \(W_l + W_{l+1} + \cdots + W_r \leq C_{\min}\).
Naive Approach and Its Issues
If we enumerate all pairs \((l, r)\), there are \(O(N^2)\) pairs, and computing the sum for each takes \(O(N^3)\) in the worst case. Using prefix sums reduces this to \(O(N^2)\), but with \(N \leq 5 \times 10^5\), we get \(N^2 = 2.5 \times 10^{11}\), which is far too slow.
Key Observation: Monotonicity
Since all candy weights are positive (\(W_i \geq 1\)), the following property holds:
- When \(r\) is fixed, decreasing \(l\) increases the sum (because more candies are included).
- If the sum exceeds \(C_{\min}\) for some \(l\), it will also exceed \(C_{\min}\) for any smaller \(l\).
Because of this monotonicity, we can use the two pointers technique.
Algorithm
We solve this using the two pointers technique.
- Compute \(C_{\min} = \min(C_1, \ldots, C_M)\).
- Initialize
left = 0(0-indexed),current_sum = 0,ans = 0. - Move
rightfrom \(0\) to \(N-1\), performing the following:- Add \(W[\text{right}]\) to
current_sum. - While
current_sum > C_{\min}, subtract \(W[\text{left}]\) fromcurrent_sumand incrementleftby \(1\). - At this point, all intervals from \([\text{left}, \text{right}]\) to \([\text{right}, \text{right}]\) satisfy the condition. The count is \(\text{right} - \text{left} + 1\), so add it to
ans.
- Add \(W[\text{right}]\) to
Concrete Example
For \(N=4\), \(W = [3, 1, 4, 1]\), \(C_{\min} = 5\):
| right | Added | current_sum | left movement | Valid intervals | Count |
|---|---|---|---|---|---|
| 0 | 3 | 3 | none | [0,0] | 1 |
| 1 | 1 | 4 | none | [0,1],[1,1] | 2 |
| 2 | 4 | 8→5 | left: 0→1 | [1,2],[2,2] | 2 |
| 3 | 1 | 6→2 | left: 1→2 | [2,3],[3,3] | 2 |
The answer is \(1+2+2+2 = 7\) ways.
Complexity
- Time complexity: \(O(N + M)\)
- Computing \(C_{\min}\) takes \(O(M)\), and the two pointers technique takes \(O(N)\) (both
leftandrightadvance at most \(N\) times each).
- Computing \(C_{\min}\) takes \(O(M)\), and the two pointers technique takes \(O(N)\) (both
- Space complexity: \(O(N + M)\)
- Required for storing arrays \(W\) and \(C\).
Implementation Notes
\(C_j\) values can be up to \(10^{18}\), which is very large, so care must be taken to ensure prefix sums fit within 64-bit integers. Python handles this automatically with arbitrary-precision integers, but in C++ and similar languages,
long longmust be used.Fast input: Since \(N, M\) can be up to \(5 \times 10^5\), in Python we speed up input by reading all at once with
sys.stdin.buffer.read().In the two pointers technique,
leftnever exceedsright. Since all \(W_i \geq 1\) and \(C_{\min} \geq 1\), it is guaranteed that at least an interval of length 1 (a single candy) always satisfies the condition.Source Code
import sys
def main():
input_data = sys.stdin.buffer.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
M = int(input_data[idx]); idx += 1
W = [int(input_data[idx + i]) for i in range(N)]; idx += N
C = [int(input_data[idx + i]) for i in range(M)]; idx += M
C_min = min(C)
ans = 0
current_sum = 0
left = 0
for right in range(N):
current_sum += W[right]
while current_sum > C_min:
current_sum -= W[left]
left += 1
ans += right - left + 1
print(ans)
main()
This editorial was generated by claude4.6opus-thinking.
posted:
last update: