C - 山の見える展望台 / Observatory with a Mountain View Editorial by admin Editorial for printing
Claude 4.6 Opus (Thinking)Overview
Given \(N\) mountains, the problem asks to efficiently compute, for each of \(Q\) queries, the sum of beauty values of mountains whose elevation is at least a specified threshold \(L_j\).
Analysis
Naive Approach and Its Issues
The simplest method is to scan all mountains for each query and sum up \(P_i\) for mountains with elevation at least \(L_j\). In this case, each query takes \(O(N)\), resulting in \(O(NQ)\) overall. Since both \(N\) and \(Q\) can be up to \(2 \times 10^5\), this requires up to \(4 \times 10^{10}\) operations in the worst case, leading to TLE (Time Limit Exceeded).
Key Insight
Each query asks for “the sum of beauty values of mountains with elevation at least \(L_j\)”, which is in the form of the sum of elements above a certain threshold. If we sort the mountains by elevation, we can use binary search to quickly find “where the mountains with elevation at least \(L_j\) start”. Furthermore, if we precompute the sum of beauty values from that position to the end using a suffix sum, we can obtain the answer in \(O(1)\).
Concrete Example
Suppose there are 3 mountains, and after sorting by elevation they look like this:
| Index | Elevation \(Y\) | Beauty \(P\) |
|---|---|---|
| 0 | 100 | 5 |
| 1 | 300 | 8 |
| 2 | 500 | 3 |
The suffix sum suffix_sum is computed from the end:
- suffix_sum[3] = 0
- suffix_sum[2] = 0 + 3 = 3
- suffix_sum[1] = 3 + 8 = 11
- suffix_sum[0] = 11 + 5 = 16
For a query \(L = 300\), binary search finds index \(1\), and the answer is suffix_sum[1] = 11 (the sum of beauty values of mountains with elevations 300 and 500).
Algorithm
- Sort the mountains in ascending order of elevation \(Y_i\).
- Build the suffix sum. Let
suffix_sum[i]be the total beauty \(P\) of all mountains from sorted index \(i\) onward. Initializesuffix_sum[N] = 0, and compute in reverse order from \(i = N-1\) to \(0\):suffix_sum[i] = suffix_sum[i+1] + P_i. - Perform binary search for each query. Using
bisect_lefton the sorted elevation array, find the first indexposwhere the elevation is at least \(L_j\). - The answer is
suffix_sum[pos]. If no such mountain exists (pos = N), thensuffix_sum[N] = 0is returned.
Complexity
- Time complexity: \(O(N \log N + Q \log N)\)
- Sorting takes \(O(N \log N)\), building the suffix sum takes \(O(N)\), and binary search for each query takes \(O(\log N)\) repeated \(Q\) times for \(O(Q \log N)\).
- Space complexity: \(O(N)\)
- For the sorted array and the suffix sum array.
Implementation Notes
By using
bisect_left, we can accurately find the first position with elevation at least \(L_j\). The reason for usingbisect_leftinstead ofbisect_rightis to include mountains whose elevation is exactly equal to \(L_j\).By using a suffix sum, we can retrieve the sum “from a given position to the end” in \(O(1)\). This can also be achieved with a prefix sum from the beginning, but the suffix sum approach is more intuitive.
Since \(P_i\) can be up to \(10^9\) and there can be up to \(2 \times 10^5\) mountains, the total 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 used.For fast I/O, we read all input at once using
sys.stdin.buffer.read()and output results collectively using'\n'.join().Source Code
import sys
import bisect
def main():
input_data = sys.stdin.buffer.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
Q = int(input_data[idx]); idx += 1
mountains = []
for i in range(N):
Y = int(input_data[idx]); idx += 1
P = int(input_data[idx]); idx += 1
mountains.append((Y, P))
# Sort by elevation
mountains.sort(key=lambda x: x[0])
sorted_Y = [m[0] for m in mountains]
# Build suffix sum array
suffix_sum = [0] * (N + 1)
for i in range(N - 1, -1, -1):
suffix_sum[i] = suffix_sum[i + 1] + mountains[i][1]
out = []
for _ in range(Q):
L = int(input_data[idx]); idx += 1
# Find the first index where Y >= L
pos = bisect.bisect_left(sorted_Y, L)
out.append(str(suffix_sum[pos]))
sys.stdout.write('\n'.join(out) + '\n')
main()
This editorial was generated by claude4.6opus-thinking.
posted:
last update: