A. Towers of Boxes
floor, ceil division などの計算問題です.
B. Beautiful Numbers
$x\geq 10$ ならば $F(x)<x$ です.digit sum では $10^nx$ が $x$ に変換されるため,$n>0$ かつ $x>0$ の文字があると減ります.
なので,digit sum を $9$ 以下にすることが目標です.leading zero を作らないように注意して貪欲に減らします.
C. Test Generator
二分探索で解きます.判定を考えます.
言い換え問題文として,「価値 $2^i$ のコインが $n$ 枚ずつある.合計を $s$ にできるか?」というものです.上位コインの価値が下位コインの価値の倍数になっているので強いコインから貪欲に使っていけば判定できます.
D. Divisibility Game
array $a$ は変化しないので,問題設定は単に,$b$ の要素ごとに,A, B それぞれがとれるか否かが定まっているということです.解法はこれの判定パートと,ゲームパートに分けられます.
まずそれぞれ A, B が取れるか判定します.各 $b$ の要素について $A$ に含まれる約数の個数を数えればよいです(頻度列を約数関係についてゼータ変換する).
ゲームパートは,単に自分しか取れないものは後回しにする貪欲をシミュレートすればよいです.
E. Probabilistic Card Game
Bob の戦略ですが,$a<b_1<b_2$ のとき $b_1$ の方が $b_2$ より得で,$a$ の右側からとるなら $a$ の最寄りの右側を選ぶとしてよいです.左側の場合も同様です.
Alice の戦略を考えます.Bob が左右からとったときのスコア $left(a), right(a)$ を考えると,left は単調増加,right は単調減少です.これらの max が $a$ を選んだときのスコアです.これは $left(a), right(a)$ の大小が切り替わるところを境界とする単峰関数です.
単峰関数の min を求めたいので,三分探索などをすればよいです.
より詳しい実装としては,$n$ 個のカードがあるときに Alice がその中での $k$ 番目を選んだとして,スコア $f(k)$ を計算するというようにします.$f(k)$ を求めるところにも何らかの $\log$ をつけた $O(N\log N\log A)$ で解きました.
F. Binary Search with One Swap
二分探索の様子を木で表しておきます.
まずは $i,j$ をスワップしたときのスコアを考えます.
- $x<i$ となる $x$:$i,j$ との比較結果は同じなので good.
- $j<x$ となる $x$:$i,j$ との比較結果は同じなので good.
- $i<x<j$ となる $x$:$i,j$ どちらかとの比較が行われた瞬間に失敗が確定します.したがって,$i$ の右部分木または $j$ の左部分木に入るものは bad,そうでなければ good ということになります.
あとは $x=i,j$ を考えます.これは当然,二分探索でスワップされたノードに向かって進んでしまうので,基本的には bad です.ただし,subtree 関係となっている場合にだけ good になります.例えば元の木で $j$ が $i$ の subtree にあるとします.スワップ後にはどちらもまず(スワップ前の)$i$ のノードまで到達します.よって $j$ は good になります.ここに到達した直後に $i$ が移動する方向を考えると,このとき $i$ は bad であることが確認できます.
結局次のようになります.$i<j$ とします.
- 先祖関係にない $(i,j)$:$i$ の右部分木,$j$ の左部分木の要素数の和に $2$ を加えたものが bad な個数.
- $i$ が $j$ の左部分木内にある場合:$[i,j)$ が bad です.
- $j$ が $i$ の右部分木内にある場合:$(i,j]$ が bad です.
計算について.すべての $i,j$ に対する beauty が最初のケース(右部分木,左部分木サイズの和から決まる)だと思って計算します.そのあと祖先子孫の関係にあるペアを補正します.
どちらも二分探索から作られた木であることを踏まえると簡単です.最初の計算は subtree size として現れる非負整数の種類数が $O(\log N)$ しかないことから行えます.祖先子孫の関係にある場合の補正ですが,そもそもこのような組 $(i,j)$ は $O(N\log N)$ しかありません.高さが $O(\log N)$ なので,子孫側から数えると分かります.
以上で $O(N\log N)$ 時間などで解けると思います.ただし,制約がかなり大きいので実装によっては TLE, MLE などに注意が必要だと思います.
私は $(i,j)$ の列挙について,祖先から見て子孫をループしましたが,子孫から見て祖先をループした方が parent 配列ひとつで済むので簡単だったかもしれません.
