問題. 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 - 忘れても大丈夫
が求まらな〜いと悩みすぎた.
は実験で
と
の
となるものを見つけて求めた.この問題を爆速で解く人たちは凄いな.