L - (Binary Search)^{-1}

2 secs 1024 MB
uni_kakurenbo's icon uni_kakurenbo

概要

数式とうまく対話して AC を手に入れましょう.

問題原案:kusirakusira

解説

Writer 解

正の整数 n,kn, k を適当に固定します.

n-n\text{-}guesser において,kk 回目の質問で Contestant 君が尋ねる実数は n2kr  (r{1,3,,2k1})\dfrac{n}{2^k}r \; (r \in \{\, 1, 3, \ldots, 2^k - 1 \,\}) と表されるものに限られることに着目します.

したがって,鍵 xx がちょうど kk 回目の質問によって特定されうるとき,xx は以下の条件を満たします:

  • xn2kr<12  (r{1,3,,2k1})\displaystyle \left|x - \frac{n}{2^k}r \right| < \frac{1}{2} \; (r \in \{\, 1, 3, \ldots, 2^k - 1 \,\})

これは必要条件ですが,十分条件ではないことに注意してください.kk未満の質問によって特定されるような xx の範囲も含まれています.

この問題で要求されていることは,(x,k)=(X,K)(x, k) = (X, K) であるとき,ちょうど kk 回目の質問で xx が特定されるような整数 nn の値を数え上げることです.

私たちの関心があるのは nn なので,nn について整理します:

  • xn2kr<12x12<n2kr<x+12(2x1)2k1<nr<(2x+1)2k11r(2x1)2k1<n<1r(2x+1)2k11r(2x1)2k1<n<1r(2x+1)2k1\displaystyle \left|x - \frac{n}{2^k}r \right| < \frac{1}{2} \\[4pt] \displaystyle x - \frac{1}{2} < \frac{n}{2^k}r < x + \frac{1}{2} \\[4pt] \displaystyle (2x - 1)2^{k-1} < nr < (2x + 1)2^{k-1} \\[4pt] \displaystyle \frac{1}{r}(2x - 1)2^{k-1} < n < \frac{1}{r}(2x + 1)2^{k-1} \\[4pt] \displaystyle \left \lfloor \frac{1}{r}(2x - 1)2^{k-1} \right \rfloor < n < \left \lceil \frac{1}{r}(2x + 1)2^{k-1} \right \rceil \\[4pt]
    • r{1,3,,2k1}r \in \{\, 1, 3, \ldots, 2^k - 1 \,\}

この条件を満たすような整数 nn の集合を F(x,k)F(x, k) と書くことにすると,私たちの知りたい値は以下の集合の要素数です:

  • F(X,K)1k<KF(X,k)\large \displaystyle F(X, K) \setminus \bigcup_{1 \leq k < K} F(X, k)

これは,F(x,k)F(x, k)2k12^{k-1} 個の区間の和集合であることに注目すると,たとえば imos 法を用いて worst Θ(K22K)\Theta(K^{2}2^{K}) 時間や expected Θ(K2K)\Theta(K2^K) 時間などで処理できます.

なお上述の議論では省略しましたが,nXn \geq X という条件に注意してください.

解説:uni_kakurenbo

Tester 解

各質問において、 llrr のどちらが動いたかを考えてみます。

l=Ln,r=Rnl=Ln,r=Rnとなるように実数 L,RL,R を定めます。はじめ、 L=0,R=1L=0,R=1 です。

Judge君が質問する実数は 12(l+r)\frac{1}{2}(l+r) です。ここで、 12(l+r)=Mn\frac{1}{2}(l+r)=Mn となるような実数 MM を考えます。

l=Ln,r=Rnl=Ln,r=Rn なので、12(l+r)=12(Ln+Rn)=L+R2n\frac{1}{2}(l+r) = \frac{1}{2}(Ln+Rn) = \frac{L+R}{2} n となり、 MML,RL,R から計算することができます。

ii (1ik1)\scriptsize ( 1 \leqq i \leqq k-1) 回目の質問によって llrr のどちらが動いたかを考えます。

ll が動いた場合、 MnX12nX12MMn \leqq X - \frac {1}{2} \Leftrightarrow n \leqq \frac{X - \frac {1}{2}}{M} となり、 L=ML=M となります。

rr が動いた場合、 X+12MnX+12MnX + \frac{1}{2} \leqq Mn \Leftrightarrow \frac{X + \frac{1}{2}}{M} \leqq n となり、 R=MR=M となります。

これらの、 nn の上限と下限を更新していくことで、 nn としてあり得る区間を不等式で表すことができます。

この不等式を anba \leqq n \leqq b ( a,ba,b は実数)とします。

l,rl,r が一回も動かない場合が存在しますが、 Xn(X+12)2KX \leqq n \leqq (X + \frac{1}{2}) 2^K なので、aa の初期値を XXbb の初期値を (X+12)2K(X + \frac{1}{2}) 2^K などにしておけばよいです。

( n=(X+12)2Kn=(X + \frac{1}{2}) 2^K のとき、AAA君が ii (1iK)\scriptsize (1 \leqq i \leqq K) 回目に質問する実数は (X+12)2Ki(X + \frac{1}{2}) 2^{K-i} であり、これはどのようなiiでも X+12X + \frac{1}{2} 以上なので、 nn はこれより小さいことがわかります)

kk 回目の質問では llrr も動かずゲームが終了するので、 X12<Mn<X+12X12M<n<X+12MX - \frac{1}{2} < Mn < X + \frac{1}{2} \Leftrightarrow \frac{X - \frac{1}{2}}{M} < n < \frac{X + \frac{1}{2}}{M} となります。

この不等式を c<n<dc < n < d ( c,dc,d は実数)とします。( ccdd は必ず存在するので、実は aabb の初期値は明らかな上限と下限、例えば 1018-10^{18}1018{10^{18}} などでもよいです)

anba \leqq n \leqq b かつ c<n<dc < n < d ( a,b,c,da,b,c,d は実数)であるような整数 nnO(1)O(1) で数え上げることができます。(参考:整数と実数と不等号と切り上げと切り捨て - noshi91のメモ)

結局、 llrr の動き方をすべて調べることで、条件を満たす整数nnを数え上げることができます。また、それぞれの nn-guesserに対しての l,rl,r の動き方は一意に定まるため、数え上げた整数が重複することはありません。

よって、bit全探索や再帰関数などで llrr の動き方を 2K12^{K-1} 通り全探索すれば、全体として Θ(K2K)\Theta(K2^K)Θ(2K)\Theta(2^K) で答えを求めることができます。

実装の補足(実数の変数について):

この問題では、 1X<240,1K121 \leqq X < 2^{40},1 \leqq K \leqq 12 なので、 0a,b,c,d<(X+12)2K<240×212=2520 \leqq a,b,c,d < (X + \frac{1}{2}) 2^K < 2^{40} \times 2^{12} = 2^{52} であり、仮数部が52bitであるC++のdoubleやPythonのfloat(デフォルトの浮動小数点数)などを用いて実装できます。また、 a,b,c,da,b,c,d はすべて有理数の四則演算で表すことができるので有理数であるため、分数で表し、分母と分子を持っておいて頑張って実装することも可能です。

解説:FplusFplusF

実装例

Writer 解

C++
Python

\\

Tester 解

Pyhon
Python