AtCoder Regular Contest 185 A,C,D問題メモ

A - mod M Game 2

問題文

  • 正整数 $N, M$ があります。ここで $N \lt M$ が成り立ちます。
  • Alice と Bob がゲームをします。$2$ 人は $1, 2, \dots, N$ が書かれたカードを $1$ 枚ずつ、合計 $N$ 枚のカードをそれぞれ持っています。
  • ゲームは以下のように進行します。
    • Alice を先攻として $2$ 人が交互に「手札を $1$ 枚選び、場に出す」という操作を繰り返します。
    • カードが場に出た直後に、今まで場に出たカードに書かれている数の総和が $M$ で割り切れる状態になったら、直前にカードを出した人の負け、そうでない人の勝ちとなります。
    • 上の条件を満たすことなく両者が持っているカードを全て出し切った場合は Alice の勝ちとなります。
  • 双方が最適に行動した時、Alice と Bob のどちらが勝ちますか?
  • $T$ 個のテストケースが与えられるので、それぞれに対して答えを求めてください。

制約

  • $1 \leq T \leq 10^5$
  • $1 \leq N \lt M \leq 10^9$
  • 入力される値は全て整数

解法

論理クイズ的問題。

$N \lt M$ なので、双方とも、手元に2枚以上のカードが残っているときは必ず負けを回避できる。

Bobが勝つためのチャンスは一度きり。
Aliceがラス1を出したときに $M$ の倍数となるように、Bobが仕向けられるかにかかっている。

このとき、場にあるカードの総和は $N(N+1)-(Bobが最後に残したカード)$ で、Bobだけがこの値を操作できる。

$b=N(N+1) \mod{M}$ とすると、$b$ を残すことで、ラス1の値を $M$ の倍数にできる。
$b=0$ または $b \ge N+1$ なら、そもそも初期の手持ちにないのでできず、Aliceの必勝である。

$1 \le b \le N$ なら手持ちにあるのでBobは $b$ を残すと勝つことができる。

残る問題は、Bobがそれまでに負けることが無いか?

Bobの手持ちが3枚以上なら、選択肢が2つ以上あるので負けることはない。
Bobがラス2のカードを出すとき、$b$ を残すように出さなければならず自由度が無い。
Bobが負けることがあるとすれば、このタイミングである。

しかし、Alice,Bob が互いにラスト1枚(それぞれ $a,b$ とする)を持っているとき、 場の総和は $N(N+1)-a-b \equiv -a \mod{M}$ である。

$N \lt M$ より、これは $M$ の倍数になることはないので、Bobがラス2の時に負けることはない。

したがって、$N(N+1) \mod{M}$ が $1~N$ の間ならBobの勝ち、それ以外ならAliceの勝ちと判定できる。

Python3

C - Sum of Three Integers

問題文

  • 整数列 $A = (A_1, A_2, \dots, A_N)$ および整数 $X$ が与えられます。
  • 次の条件を全て満たす整数の組 $(i, j, k)$ を $1$ 組出力してください。
    • $1 \leq i \lt j \lt k \leq N$
    • $A_i + A_j + A_k = X$
  • 条件を満たす組が存在しない場合はそのことを報告してください。

制約

  • $3 \leq N \leq 10^6$
  • $1 \leq X \leq 10^6$
  • $1 \leq A_i \leq X$
  • 入力される値は全て整数

解法

2数を仮定したらあと1数が存在するかチェックすればよいが、そもそも2数の仮定が $O(N^2)$ なのでできない。

後述の解法をするに当たって、$A$ に同じ値が含まれ、 それを2、3回使うような解があった場合、少し判定がややこしくなる。
そういうのは $O(N)$ で判定できるので最初にしてしまい、 「解があるとしたら3数がバラバラの組である」という状態にしてしまう。

重複を除いた $A$ を $A'$、長さを $M$ とする。

$F(x):=x^{A'_1}+x^{A'_2}+...+x^{A'_M}$ とし、$F^2$ を畳み込みで計算することで 「和が $y$ となる2数が存在するか?」を、任意の $y$ について $O(1)$ で判定できるようになる。

ただし、$F^2$ には同じ2数を重ねて選んだものも含まれているため、それは除いておく。
$i=1,...,M$ について、$F^2$ から $x^{2A'_i}$ を引けばよい。

後は、残り1数 $A'_i$ を固定し、$X-A'_i$ が2数の和として存在すればその2数を $O(M)$ で確認すればよい。

Python3

D - Random Walk on Tree

問題文

  • 頂点に $0, 1, \dots, N \times M$ の番号がついた $N \times M + 1$ 頂点の木があります。
    • $i$ 本目の辺 $(1 \leq i \leq N \times M)$ は頂点 $i$ と頂点 $\max(i - N, 0)$ を結ぶ辺です。
    • また、頂点 $0$ には色が塗られています。それ以外の頂点は色が塗られていません。
  • 高橋君は頂点 $0$ にいます。高橋君は色が塗られていない頂点が存在する間、次の操作を行います。
    • 自身がいる頂点に隣接する頂点の中から一様ランダムに頂点を $1$ つ選んで、その頂点に移動する。(全ての選択は独立である。) そして、今いる頂点に色が塗られていなければ色を塗る。
  • 操作を行う回数の期待値を $\text{mod }998244353$ で求めてください。

制約

  • $1 \leq N \leq 2 \times 10^5$
  • $1 \leq M \leq 2 \times 10^5$
  • $N, M$ は整数

解法

こんなグラフである。

0---1--5--9   ^
 |--2--6--10  |N
 |--3--7--11  |
 `--4--8--12  v
   <---M--->

どの枝に入ったとしても、結局、最奥の頂点まで到達しなければ意味が無い。
最奥の頂点が塗られないまま0に戻ったら、結局、最奥を塗るために再度その枝が選ばれないといけない。

「0からある枝に入ったとき、その枝の中で、最奥まで行くか、行かずに戻るか」などで分類して確率・期待値を計算しようと思うと、「最奥まで到達する確率」「しない確率」「する場合の回数期待値」「しない場合の回数期待値」など収拾が付かなくなる。

こう考えるとスムーズである。

  • 頂点0から、どれかの枝の最奥に最初に至る回数期待値を $E$ とする。
    • この時、途中で0まで戻って複数の枝にまたがって移動が発生するかもしれないが、かまわない。
    • あくまで「どこかの最奥まで辿り着く」までの回数が重要。

$E$ は、以下のグラフで「頂点 $i$ からスタートして最奥に至るまでの回数期待値を $E(i)$」として、$E(0)$ を求めれば良い。

M=3
0---1---2---3
  • $E(3)=0$
  • $E(2)=1+\frac{E(1)+E(3)}{2}$
  • $E(1)=1+\frac{E(0)+E(2)}{2}$
  • $E(0)=1+E(1)$

$E(3)$ はゴールなので $0$ となる。$E(0)$ は必ず1に移行するので少し遷移が異なる。

この $E(0)$ は結果的に $M^2$ になるが、それを知らなくても $O(M)$ かけて計算してもよい。
$E(M)=0$ から順に代入していくことで、$E(0)$ を求めることができる。

また、$E$ は左右反転させれば「どれかの最奥から、0まで戻るための回数期待値」とも等しくなる。

すると、これは1回引くのにコストが往復分で $2E$ かかる、$N$ 個を揃えるコンプガチャと見ることができる。

コンプガチャを引く回数期待値は、$F=\frac{N}{N}+\frac{N}{N-1}+...+\frac{N}{1}$ となる。

ただし、この問題では最後の頂点をコンプした後のみ0に戻らなくてよいため、その分は減算できる。

答えは、$(2F-1)E$ となる。

Python3

programming_algorithm/contest_history/atcoder/2024/1013_arc185.txt · 最終更新: 2024/10/22 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0