Codeforces Round #555 (Div. 3) E. Minimum Array

問題概要

長さ  n の数列 a ,b が与えられます.  a, b の各要素は  0 以上  n-1 以下です. 

数列  c を,  c_i = (a_i + b_i)~\mathrm{mod}~n として定めます.  b の各要素を自由に入れ替えて,  c が辞書順最小にしてください.

問題へのリンク

制約

  •  1 \le n \le 2\times 10^5
  •  0 \le a_i, b_i \le 2\times 10^5

解法

辞書順最小と言われれば, やっぱり貪欲法です.  i の小さい方から見ていくことにするとき,  a_i に合わせたい数字は何でしょうか?

これは  (n-a_i)~\mathrm{mod}~n を合わせた時が最もうれしく,  c_i 0 になります. この値から  b_i 1 増えるごとに,  c_i 1 ずつ増えていきます. この嬉しさが毎回最大になるように貪欲に選び続ければいいです. 

この貪欲に選び続ける方法は二通りの実装があって, ひとつ目は  cnt_i := (b_i = i)となる  b_i の数みたいに定義して毎回自分より左で一番小さい要素を二分探索することです. 二周ぶんつくれば実装が多分楽です.

もう一つはセグ木でなんとかすることです. セグ木に  \{index, cnt\} みたいな感じでのせて,  cnt0 になったら  \{\infty, \infty\} を入れます. あとは区間最小値を取ってくるだけです(詳しくは実装を見てください).

実装

多分もっと楽な実装がある

Submission #145097371 - Codeforces