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