A. Kibr and His Musics
Problem Overview:
The problem involves identifying which song is playing at specific moments during a playlist where each song repeats a defined number of times. The playlist plays sequentially, with song i
playing ci
times and each play lasting ti
minutes. Given moments vi
, we need to determine which song is playing at each of those times.
Approach:
Prefix Sum Array: The key idea is to build a prefix sum array where prefix[i]
represents the cumulative total duration of songs from the start to the end of song i
. If ci
is the repetition count and ti
is the duration of song i
, then the contribution of song i
to the prefix sum is ci * ti
. The prefix sum allows us to efficiently check which song is playing at any given moment by comparing the vi
values against cumulative durations.
Linear Search: For each moment vi
, iterate through the prefix sum array until you find the first i
where prefix[i] >= vi
.
Time Complexity:
Prefix Sum Construction: O(n)
Query Handling: O(m) using linear search
Overall: O(n + m)
Space Complexity: O(n) for storing the prefix sum array.
n, m = map(int, input().split())
prefix = []
for i in range(n):
c, t = map(int, input().split())
prefix.append(c * t)
if i > 0:
prefix[i] += prefix[i - 1]
moments = list(map(int, input().split()))
i = 0
for j in range(m):
while prefix[i] < moments[j]:
i += 1
print(i + 1)
B. Kidus Couldn't Sleep
To efficiently calculate the average sleep time, consider how to sum values over sliding windows without recalculating the entire sum for each new window.
The problem requires calculating the average sleep time over all possible weeks in Polycarp's records. A naive approach would involve iterating through each possible starting index and summing up the next k elements. However, this results in an O(n × k) complexity, which is inefficient for large values of n. Instead, we can use the sliding window technique to efficiently compute the sum for each week in O(n) time:
- First, compute the sum of the first k days and store it as the current sum.
- Iterate from day k to day n, updating the sum by adding the new day's sleep time and removing the sleep time of the day that is no longer in the window.
- Keep a running total of these weekly sums and compute the final average.
n, k = map(int, input().split())
a = list(map(int, input().split()))
curr = sum(a[:k])
total = curr
for i in range(k, n):
curr += a[i] - a[i - k]
total += curr
print(total / (n - k + 1))
C. Restoring to the Original
D. Socialism
Try to find the maximum number of people who can have at least x burles after redistributing the money among selected subsets of people. The key observation is that the redistribution must be fair among the chosen subset.
The problem requires us to maximize the number of people who have at least x
burles after any number of redistribution reforms. The key observation is that any subset of people chosen for redistribution will end up with an equal amount of money per person.
Approach:
- Sort the savings in descending order: This ensures that we consider the wealthiest individuals first.
- Iterate through the sorted list and track cumulative wealth: We keep summing the wealth and checking if the average wealth of the first
i
people is at leastx
. - Break when the condition fails: If at any step the cumulative wealth divided by
i + 1
is less thanx
, the answer isi
. Otherwise, the answer isn
if we can include all individuals.
Example Walkthrough:
- Case 1 (
[5,1,2,1]
,x=3
):
- Sort:
[5,2,1,1]
- Sum stepwise:
5
,5+2=7
,7+1=8
,8+1=9
- The condition fails at index
2
, so the answer is2
.
- Case 2 (
[11,9,11,9]
,x=10
):
- Sort:
[11,11,9,9]
- Sum stepwise:
11
,22
,31
,40
- The condition holds for all, so the answer is
4
.
- Case 3 (
[4,3]
,x=5
):
- Sort:
[4,3]
- The sum never reaches
5
, so the answer is0
.
- Case 4 (
[9,4,9]
,x=7
):
- Sort:
[9,9,4]
- Sum stepwise:
9
,18
,22
- The condition holds for
3
, so the answer is3
.
Complexity Analysis:
- Sorting takes O(n log n).
- Iterating through the array takes O(n).
- Thus, the total complexity per test case is O(n log n).
- Since the sum of
n
across all test cases is at most10^5
, this solution efficiently handles the constraints.
t = int(input()) # Read number of test cases
for _ in range(t):
n, x = map(int, input().split()) # Read n (number of people) and x (wealth threshold)
nums = sorted(map(int, input().split()), reverse=True) # Sort wealth in descending order
total = 0 # Track cumulative wealth
for i in range(n):
total += nums[i] # Add wealth of the i-th person
if total < x * (i + 1): # Check if the average wealth falls below x
print(i) # Maximum number of wealthy people possible
break
else:
print(n) # If we never break, all n people can be wealthy
E. TV Off
F. Covered Points Count
- What would you do if the constraints for the coordinates were up to (10^5)?
- You could use the line sweep algorithm, but the coordinates go up to (10^9). So, what shall we do?
- What if you use a dictionary instead of an array to store only the relevant positions?
We perform a line sweep using a dictionary to record events at positions where the number of covering segments changes. Sorting the dictionary keys lets us compute the prefix sum between these "critical" points. For each interval ([prev, cur)), the number of integer points is ((cur — prev)) and they are all covered by the current number of segments. This way, we aggregate the answer for every (k) in ([1, n]) without iterating over every integer in a huge range.
import sys
from collections import defaultdict
n = int(sys.stdin.readline().strip())
events = defaultdict(int)
# Record events: +1 when a segment starts, -1 when it ends (at r+1)
for _ in range(n):
l, r = map(int, sys.stdin.readline().split())
events[l] += 1
events[r + 1] -= 1
# Sort the event points
keys = sorted(events.keys())
coverage = 0
prev = keys[0]
result = defaultdict(int)
# Line sweep: update coverage and count points in intervals
for point in keys:
result[coverage] += point - prev
coverage += events[point]
prev = point
# Output counts for points covered by exactly 1 to n segments
ans = [result[k] for k in range(1, n + 1)]
print(*ans)
G. Evenly Spaced Letters
Let's consider a very special case of equal distances. What if all distances were equal to $$$1$$$? It implies that if some letter appears exactly twice, both occurrences are placed right next to each other.
That construction can be achieved if you sort the string, for example: first right down all letters '$$$a$$$', then all letters '$$$b$$$' and so on. If a letter appears multiple times, all its occurrences will be next to each other, just as we wanted.
Overall complexity: $$$O(|s|log|s|)$$$ or $$$O(|s|)$$$ per testcase.
for _ in range(int(input())):
print(''.join(sorted(input())))
H. Dominoes
I. The Odd Challenge
We have an array ( a ) of length ( n ) and must answer ( q ) queries. Each query modifies all elements in a given range ( [l, r] ) by setting them to ( k ) and asks whether the sum of the updated array is odd.
Each query is independent, meaning changes do not persist for subsequent queries.
Observe that changing a subarray to a fixed value (k) affects the total sum in a predictable way. The effect on the total sum can be computed by removing the sum of the existing subarray and adding the contribution of the new values.
How can prefix sum help us here?
- Compute the initial sum of the array.
- Compute the prefix sum for quick range sum retrieval.
- For each query:
- Compute the sum of the range ( [l, r] ).
- Replace it with ( (r — l + 1) \times k ).
- Check if the new sum is odd.
- Print "YES" if odd, else "NO".
t = int(input())
for _ in range(t):
n, q = map(int, input().split())
a = list(map(int, input().split()))
prefix = [0] * (n + 1)
for i in range(n):
prefix[i + 1] = prefix[i] + a[i]
total_sum = prefix[-1]
results = []
for _ in range(q):
l, r, k = map(int, input().split())
replaced_range_old_sum = prefix[r] - prefix[l - 1]
replaced_range_new_sum = (r - l + 1) * k
new_sum = total_sum - replaced_range_old_sum + replaced_range_new_sum
if new_sum % 2 == 1:
results.append("YES")
else:
results.append("NO")
print("\n".join(results) + "\n")
- Computing the total sum: ( O(n) )
- Computing the prefix sum: ( O(n) )
- Each query: ( O(1) ) (using prefix sum)
- Total complexity: ( O(n + q) ) per test case, which is optimal given constraints.