D - 配送センターの稼働計画 / Operation Plan for Distribution Center Editorial by admin
Gemini 3.0 FlashOverview
Given \(N\) desired delivery dates \(D_i\), the problem asks to choose an interval \([s, s+K-1]\) of length \(K\) to minimize the total distance from each \(D_i\) to the interval (0 if \(D_i\) is within the interval).
Analysis
1. Understanding the Dissatisfaction
When a package has desired date \(D_i\) and the operating period is \([s, e]\) (where \(e = s + K - 1\)), to minimize that package’s dissatisfaction, we should deliver it on the day within the period closest to \(D_i\). - When \(D_i < s\): Delivering on day \(s\) is optimal, with dissatisfaction \(s - D_i\) - When \(s \le D_i \le e\): We can deliver on day \(D_i\), with dissatisfaction \(0\) - When \(D_i > e\): Delivering on day \(e\) is optimal, with dissatisfaction \(D_i - e\)
Combining these, the dissatisfaction per package can be written as \(\max(0, s - D_i, D_i - e)\).
2. Properties of the Function and the “Median” Approach
Let \(f(s)\) be the total dissatisfaction across all packages. This function is convex (a convex-downward graph) with respect to \(s\). Consider how the slope of \(f(s)\) changes. When \(s\) increases by \(1\): - Dissatisfaction increases by \(1\) for packages where \(D_i < s\) - Dissatisfaction decreases by \(1\) for packages where \(D_i > s + K - 1\) - Dissatisfaction does not change for other packages
Therefore, the slope of \(f(s)\) is (number of packages with \(D_i < s\)) - (number of packages with \(D_i > s + K - 1\)). The location where this slope becomes \(0\) is the candidate for the minimum.
Reorganizing the conditions: - \(D_i < s\) \(\iff\) \(s > D_i\) - \(D_i > s + K - 1\) \(\iff\) \(s < D_i - K + 1\)
This suggests that the slope becomes \(0\) near the median of the \(2N\) values (\(D_i\) and \(D_i - K + 1\)). Specifically, if we sort these \(2N\) values in ascending order as \(P_1, P_2, \ldots, P_{2N}\), then \(f(s)\) is minimized for \(s\) in the range \([P_N, P_{N+1}]\).
3. Handling the Constraint \(s \ge 1\)
Since the problem requires \(s\) to be a positive integer, if the computed median range falls below \(1\), we set \(s=1\). That is, \(s = \max(1, P_N)\) minimizes \(f(s)\) while satisfying the constraint.
Algorithm
- Sort the given \(D_i\).
- Put all \(2N\) points \(\{D_i\} \cup \{D_i - K + 1\}\) into a list \(P\) and sort it.
- Set \(s = \max(1, P_N)\) (or \(P[N-1]\) in 0-indexed) as the optimal starting day.
- Compute the ending day \(e = s + K - 1\).
- For each package, compute the following total (can be sped up using prefix sums or binary search):
- If \(D_i < s\): \((s - D_i)\)
- If \(D_i > e\): \((D_i - e)\)
- Otherwise: \(0\)
Complexity
- Time Complexity: \(O(N \log N)\)
- Sorting \(D_i\) takes \(O(N \log N)\).
- Sorting \(P\) with \(2N\) elements takes \(O(N \log N)\).
- Computing dissatisfaction using prefix sums and binary search (or scanning) takes \(O(N)\) or \(O(\log N)\).
- Space Complexity: \(O(N)\)
- \(O(N)\) memory is used to store the arrays \(D, P\) and prefix sum arrays.
Implementation Notes
Efficient Computation: Since \(N=2 \times 10^5\) can be large, when computing the total dissatisfaction, instead of iterating through all elements each time, use prefix sums to obtain range sums in \(O(1)\).
Median Selection: Any value between the \(N\)-th and \((N+1)\)-th elements of the sorted \(2N\) data points gives the minimum. In the code, \(P[N-1]\) is used.
Size of \(K\) and \(D_i\): Since \(K\) and \(D_i\) can be up to \(10^9\), the answer may not fit in a 32-bit integer. In Python, this is handled automatically with arbitrary-precision integers, but in other languages,
long longor equivalent types must be used.Source Code
import sys
from bisect import bisect_left, bisect_right
def solve():
# 高速な入力を実現するためにsys.stdin.read().split()を使用
input_data = sys.stdin.read().split()
if not input_data:
return
# N: 荷物の個数, K: 稼働期間の日数
N = int(input_data[0])
K = int(input_data[1])
# D: 各荷物の希望配達日
D = [int(x) for x in input_data[2:]]
# 希望配達日を昇順にソート
D.sort()
# 稼働期間を [s, s + K - 1] としたとき、
# 各荷物に対する最小不満度は max(0, s - Di, Di - (s + K - 1)) となる。
# この不満度の合計を最小化する問題は、s に関する凸関数の最小値を求める問題であり、
# その最小値は 2N 個の点 {Di} と {Di - K + 1} の中央値の範囲内で達成される。
# 特徴点(不満度関数の傾きが変化する点)をすべてリストに加える
P = D + [x - K + 1 for x in D]
P.sort()
# 2N 個の点の中央値の範囲は [P[N-1], P[N]] となる。
# s は任意の正整数(s >= 1)である必要があるため、最適な s を以下のように選ぶ。
# 中央値の範囲が 1 以上の整数を含むならそのいずれかを、
# 範囲がすべて 1 未満なら s = 1 を選ぶことで、s >= 1 の範囲での最小値が得られる。
s = max(1, P[N - 1])
e = s + K - 1
# 不満度の合計 f(s) を計算する。
# f(s) = sum_{Di < s} (s - Di) + sum_{Di > s + K - 1} (Di - (s + K - 1))
# 計算を高速化するために累積和を準備
prefix_sum = [0] * (N + 1)
for i in range(N):
prefix_sum[i + 1] = prefix_sum[i] + D[i]
# Di < s となる荷物の個数と合計
idx_low = bisect_left(D, s)
count_low = idx_low
sum_low = prefix_sum[idx_low]
cost_low = count_low * s - sum_low
# Di > e となる荷物の個数と合計
idx_high = bisect_right(D, e)
count_high = N - idx_high
sum_high = prefix_sum[N] - prefix_sum[idx_high]
cost_high = sum_high - count_high * e
# 最小の不満度合計を出力
print(cost_low + cost_high)
if __name__ == '__main__':
solve()
This editorial was generated by gemini-3-flash-preview.
posted:
last update: