Google Code Jam 2019 Round1B : Draupnir
問題. Draupnir
-day ring と呼ばれる指輪がある.1つの -day ring は出現した日から 日ごとに -dary ring を1つ複製するということを永遠に続ける.0 日目に各 -day ring が 個出現する( は未公開).
「 日目にある指輪の総数の による剰余はいくつか」という質問を高々 回行い,すべての を求めよ.
制約: , , (ただし,少なくとも1つの は正)
解法
日目に対するクエリの戻り値を とする. は62ビットの非負整数であり問題から,
となる.2回のクエリ と ですべての を求める.
解法の前に使用するビット演算について説明する. は100以下の非負整数なので7ビットで表現可能である.ここで,整数 の二進表記を とすると, は を ビットだけ左シフトしたもので, は ビットだけ右シフトしたものである.ただし,最上位ビットは0埋めを行う.
に対するクエリの戻り値は,
となる.ここから, の値が次のように分かる.
・ は の から ビット目の値に等しい()
・ は の から ビット目の値に等しい()
・ は の から ビット目の値に等しい()
これらの値のビット列は互いに交差しないので を ビット右シフトして で剰余をとると求まる. は戻り値のビット数で表現できないので求めることができない( は下位2ビットだけ分かる).
に対するクエリの戻り値は,
となる.ここから, の値が次のように分かる.
・ は の から ビット目の値に等しい()
・ は の から ビット目の値に等しい()
これらの値のビット列は互いに交差しないので を ビット右シフトして で剰余をとると求まる.ここで, は の から ビット目の値にはならない.なぜならば, が の から ビット目の範囲となり, の領域と交差するからである.ただし,ここまでで 以外のすべての値が求まっているので,
として求めることができる.
インタラクティブ問題のローカルでのテスト方法は次を参考.
Google Code Jam 2019 Qualification Round : Dat Bae - 忘れても大丈夫
が求まらな〜いと悩みすぎた. は実験で と の となるものを見つけて求めた.この問題を爆速で解く人たちは凄いな.