この問題はadaptiveではない(クエリに依らず数列は固定されている)ものとする。愚直な二分探索まずそれなりに競プロ慣れしている人なら、「各要素に対して二分探索を行う」方法が真っ先に思いつくだろう。)のクエリが必要であり、とてもじゃないが間に合わない。小さい要素を切り捨てる最大でない要素の値を求める必要はないことから、「境界値より小さい要素を切り捨てつつ、全体で一気に二分探索をする」という方法も考えられる。投げる」→...といった具合である。回1のクエリが必要となり、大半のケースでは間に合いそうにない。あるようなケースなら尚更間に合わない。上限にとても近いことである。ここから、上手くやれば大半の要素は1回のクエリでパスできる2ことが推測される。そこで、以下のような解法が浮かんでくる。最初の解法と同様に「全要素に対して二分探索を行う」ことにする。最初の解法と違う点として、二分探索前に「これまで見た中での最大要素」でクエリを投げ、これ以下であるようなら二分探索をせずパスすることにする。回二分探索をすることになってしまう。そこで本記事の核となるアイデアが出てくる。ランダムに並び替えた順列を用意し、その順番通りに数列の値を求めていく」、ということである。これは数列をランダムにシャッフルすることに等しい。クエリ回数の期待値これでどれだけクエリ回数を削減できるのだろうか。そこでシャッフル後の数列にて最大値がどこにいるかを考えてみる。これはランダム性から、真ん中になるだろうと期待される。この最大値より右側の区間は調べる必要がないので、左側の区間について再帰的に考えればよい。上の考察にて、最大値によって区間を分割する毎に区間長は半減すると期待される。あることから高確率で制限回数内に解が求まると予想される3。今の実力では応用できる幅が少ないテクだが、考え方はとても面白い。乱択は使いようだなぁという印象。以下のスライドに上のテクニックを含む、乱択に関する諸々のテクニックが載っているので参考までに。各要素について最低1回はクエリを行わなければならないことに注意されたい。本番ならB落としてた。