ARC101/ABC107 D - Median of Medians
復習日記
解説その他諸々を見ながらやっていきます。
問題概要
- 長さの数列を昇順に並べたときの番目の要素の値を中央値とする
- 長さNの数列の各についての中央値をと置く
- すべてのに対してのを集めた数列を作り、その数列の中央値を求める
考え方
まず、中央値について考え方を整理します。問題概要には中央値の定義は、
長さの数列を昇順に並べたときの番目の要素の値を中央値とする
と書かれていますが、これを言い換えると、長さの整数列の中央値をとしたときに、
- の中に以上の要素が個以上含まれるの中で最大の整数
であるといえます。
この「条件を満たすものの中で最大のもの」という考え方に注目すると二分探索で解くことができることがわかります。
これは連続部分列の中央値を並べた数列にも同様のことが言えて、最終的にこの問題は、
- のうち以上の要素は何個か?
という質問に置き換えることができます。
ここでについて言及するように言い換えると、
- の連続部分列 のうち, 以上の要素を個以上含むものは何通りか?
という質問になります。
次に、この質問に対してどのような解法をとるかを考えます。
毎回数えてしまうと計算量が多く間に合いません。そこでより大きい数を、より小さい数をに置き換えて累積和を取ります。
そうするとその区間の累積和が0以上であればより大きい数の個数が過半数であるということがわかります。
さらに言えば、からまでの累積和を取っておけば、
と計算をすることで求めることができます。
最後に、区間の累積和が0以上である区間の個数を求める方法ですが、としたときに、
- であるの組み合わせの個数
と言い換えることができます。これは反転数を求めるアルゴリズムを使うと高速に求めることができます。 反転数のアルゴリズムについては蟻本のp162または螺旋本のp175に載っています。
提出コード(諸々を写経)
かなり難しい700点ですね…
これを時間内に解くだけパフォーマンスが2000を超えるので、目標にしたいところです。