Table of Contents

ExplanationImplementation

Official Analysis (C++, Python)

Explanation

The problem asks us to minimize the sum of aix|a_i - x| for all aia_i, using an xx of our choice, with each difference under modulo MM (strictly, optimizing the sum of min(aixmodM,xaimodM)\min(a_i - x \bmod M, x - a_i \bmod M)). Thus, let us first consider this problem without the modulus.

Letting xx be the median of those numbers minimizes the total distance. In the case that NN is even, any number between the two numbers in the middle (inclusive) would work.

We now consider the modulus. First, take each number modulo MM. Observe that any element can be the median if we add or subtract MM from some elements, shifting some values to the left and right of the element. For example, given [1,3,7,9,13,17,19][1,3,7,9,13,17,19] and M=24M = 24, we can make 1717 the median by adding MM to elements 11 and 33, resulting in the array [7,9,13,17,19,25,27][7,9,13,17,19,25,27].

Thus, every element is a candidate for xx. We compute the cost for each xx after shifting, and take the best candidate, which is the xx that results in the smallest sum of absolute differences.

To implement this, we first sort aa. Then, we consider each element in a as a potential xx. For each candidate value, we compute either the number of elements before it that must be increased by MM or the number of elements after it that must be decreased by MM in order to make this value the median. After that, we use prefix sums to compute the total absolute difference. However, this requires us to access indices of aa that are not in the [0,n)[0, n) range; to mitigate this, we prepend to aa a copy of aa with MM subtracted from every element, and append a copy of aa with MM added to every element. The range [n,2n)[n, 2n) in aa will then be the original elements we enumerate over, and we will be able to access the elements that come before or after the original array.

The final answer will be the smallest sum of absolute differences over all such indices.

Implementation

Time Complexity: O(NlogN)\mathcal{O}(N \log N) per test case

t = int(input())
for _ in range(t):
n, m = map(int, input().split())
nums = list(map(int, input().split()))
# Mod, sort, and construct array
rems = sorted([x % m for x in nums])
# s is prepended/appended array
s = [x - m for x in rems] + rems + [x + m for x in rems]

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!