C - 本棚の整理 / Organizing the Bookshelf Editorial by admin
Claude 4.6 Opus (Thinking)Overview
This problem asks us to find a contiguous subarray whose total weight is at most \(K\) and whose total satisfaction is maximized. It can be solved efficiently using the two pointers (sliding window) technique.
Analysis
Naive Approach and Its Issues
If we try all intervals \([l, r]\), there are \(O(N^2)\) combinations of \(l\) and \(r\). Even if we compute the weight and satisfaction of each interval in \(O(1)\) using prefix sums, since \(N\) can be up to \(2 \times 10^5\), \(O(N^2)\) would require approximately \(4 \times 10^{10}\) operations, which exceeds the time limit (TLE).
Key Observation
This problem has the following properties:
- The weights \(B_i\) are all positive values (at least \(1\))
- Therefore, expanding the interval to the right causes the total weight to monotonically increase
- Conversely, shifting the left endpoint to the right causes the total weight to monotonically decrease
Because of this monotonicity, when the right endpoint \(r\) is fixed, the range of left endpoints \(l\) for which the weight is at most \(K\) forms a contiguous range from some value onward. Furthermore, when \(r\) increases by \(1\), the lower bound of valid left endpoints either stays the same or moves to the right. In other words, the left endpoint never moves backward.
This property allows us to apply the two pointers technique.
Concrete Example
For example, with \(N=5\), \(K=10\), \(A = [3, 5, 2, 8, 1]\), \(B = [4, 3, 5, 6, 2]\):
- \(r=0\): Interval \([0,0]\), weight \(4 \leq 10\) → satisfaction \(3\)
- \(r=1\): Interval \([0,1]\), weight \(7 \leq 10\) → satisfaction \(8\)
- \(r=2\): Interval \([0,2]\), weight \(12 > 10\) → advance left to \([1,2]\), weight \(8 \leq 10\) → satisfaction \(7\)
- \(r=3\): Interval \([1,3]\), weight \(14 > 10\) → advance left to \([2,3]\), weight \(11 > 10\) → advance further to \([3,3]\), weight \(6 \leq 10\) → satisfaction \(8\)
As shown, the left endpoint never moves backward, and the entire process runs in \(O(N)\).
Algorithm
- Initialize the left endpoint
leftto \(0\), and initialize the total weightsum_band total satisfactionsum_ato \(0\) - Move the right endpoint
rightfrom \(0\) to \(N-1\) in order:- Add \(A[\text{right}]\) to
sum_aand \(B[\text{right}]\) tosum_b - While
sum_b > K, remove the leftmost book from the interval (subtract \(A[\text{left}]\) and \(B[\text{left}]\) fromsum_aandsum_b, and incrementleftby \(1\)) - If the current
sum_ais greater than the current maximum answer, update the answer
- Add \(A[\text{right}]\) to
- Output the final maximum value
Complexity
- Time complexity: \(O(N)\) —
rightadvances \(N\) times, andleftadvances at most \(N\) times in total, so the combined total is \(O(N)\) - Space complexity: \(O(N)\) — needed to store arrays \(A\) and \(B\)
Implementation Notes
Since \(K\) can be up to \(10^{15}\), each \(B_i\) up to \(10^9\), and \(N\) up to \(2 \times 10^5\), the total weight can reach approximately \(2 \times 10^{14}\). In Python there is no need to worry about integer overflow, but in C++ and similar languages,
long longmust be usedWhen advancing the left endpoint in the
while sum_b > Kloop,leftwill never exceedright(because there always exists at least one interval consisting of a single book whose weight is at most \(K\))sys.stdin.buffer.read()is used for fast inputSource Code
import sys
def main():
input_data = sys.stdin.buffer.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
K = int(input_data[idx]); idx += 1
A = [int(input_data[idx + i]) for i in range(N)]; idx += N
B = [int(input_data[idx + i]) for i in range(N)]; idx += N
ans = 0
sum_a = 0
sum_b = 0
left = 0
for right in range(N):
sum_a += A[right]
sum_b += B[right]
while sum_b > K:
sum_a -= A[left]
sum_b -= B[left]
left += 1
if sum_a > ans:
ans = sum_a
print(ans)
main()
This editorial was generated by claude4.6opus-thinking.
posted:
last update: