yukicoder contest 283 G 誕生日プレゼント 別解解説

 writer解・tester解と異なる方法で解いたので紹介します。

問題

yukicoder contest 283 G ★4.5 誕生日プレゼント
問題リンク:https://yukicoder.me/problems/no/1404

要約:
 長さ NN の整数列 AA , BB が与えられるので、次の操作を合計 PP 回以下行って AABB に一致させよ。不可能ならそれを報告せよ。

  • 操作 11 : i,j i,j を選んで Ai A_i Aj A_j を加算。
  • 操作 22 : A A の要素すべてに mod P \mathrm{mod} \ P を適用する。

制約:

  • 1N105 1 \le N \le 10^5
  • P=223577 P=223577 ( 素数 )
  • 0Ai,Bi<P 0 \le A_i, B_i \lt P

解説

利用する有名テクニック一覧

  • ダブリング・繰り返し二乗法
  • mod \mathrm{mod} 素数における四則演算
  • 平方分割

簡単な場合分け

操作 2 2 は最後に 1 1 回だけ行う。
A A または B B がすべて 0 0 の場合と、 N=1 N=1 の場合を排除できる。

 操作 2 2 を最後に行うことにすれば、途中の操作 1 1 をすべて mod P \mathrm{mod} \ P で行うものとしてよいです。以下、操作 1 1 mod P \mathrm{mod} \ P で行い、途中の操作 2 2 は考えません。

 A A がすべて 0 0 のとき、 B B がすべて 0 0 なら 0 0 回の操作で目的が実現可能で、そうでなければ実現不可能です。逆に、 B B がすべて 0 0 A A が「すべて 0 0 」ではない場合は、 B B から始めて本来と逆の操作を考えると、実現不可能であることがわかります。

 N=1 N=1 のとき、唯一可能な操作「 A1 A_1 A1 A_1 を足す」を P1 P-1 回繰り返す間に、 B B に一致するか確かめます。試してみると 2(P1)/41 (mod P) 2^{(P-1)/4} \equiv 1 \ ( \mathrm{mod} \ P ) より (P1)/4 (P-1)/4 回で A1 A_1 の値が元に戻るので、操作 11(P1)/41 (P-1)/4-1 回以下になります。

任意の値を 36 36 回の操作で生成

Ai0 A_i \ne 0 ならば、 36 36 回以下の操作で Aj A_j (ij) ( i \ne j ) を任意の値にできる。

 A1=0,A2=1 A_1 = 0 , A_2 = 1 のとき、操作 X \mathrm{X} A1 A_1 2 2 倍して、 A2 A_2 A1 A_1 0 0 回か 1 1 回足す」 を K K 回繰り返すと、 A1 A_1 0 0 以上 2K1 2^K-1 以下の任意の整数にできます (ダブリング) 。操作はそのままで A1=s,A2=t A_1 = s , A_2 = t とすると A1 A_1 2Ks+tx 2^K s + t x (mod P) ( \mathrm{mod} \ P ) ( x x 0 0 以上 2K1 2^K-1 以下の整数 ) にできます。 K K P2K P \le 2^K を満たし、 t0 t \ne 0 であれば、この値の集合は 0,1,,P1 (mod P) 0,1, \dots ,P-1 \ ( \mathrm{mod} \ P ) をすべて含みます。

 目的の値 kk のために操作の手順を復元するには x x の値が必要ですが、 k=2Ks+tx k = 2^K s + t x x x について解くと x=(k2Ks)/t x = ( k-2^K s ) / t で求まります。

 2KP 2^K \le P のためには K=18 K = 18 でよく、操作 X \mathrm{X} は、 2 2 回以下の操作 1 1 で再現できるので、この手順全体は 36 36 回でできます。

値の平方分割

N N が大きいとき、 N N 1 1 増えると操作回数が高々 2 2 増える。

 考えられる方針は複数ありますが、値を平方分割すればうまくできます。

 P500 \sqrt{P} \le 500 を考えます。数列 A A 中に 1,2,3,,499 1,2,3, \dots ,499 500,1000,1500,,500×499 500,1000,1500, \dots ,500 \times 499 を出現させ、他の要素に適宜足すことで、他の要素 1 1 つあたり高々 2 2 回の操作で B B と一致させられます。これを次の手順で実現します。

  • A1=1,A2=1 A_1 = 1 , A_2 = 1 とする。
  • A1 A_1 A2 A_2 を足す操作を A1=499 A_1 = 499 まで繰り返しながら、適宜 A3 A_3 AN A_N A1 A_1 を足す。
  • A1=500,A2=500 A_1 = 500 , A_2 = 500 とする。
  • A1 A_1 A2 A_2 を足す操作を A1=500×499 A_1 = 500 \times 499 まで繰り返しながら、適宜 A3 A_3 AN A_N A1 A_1 を足す。

 この手順は 2N+500×2+36×4201144 2N + 500 \times 2 + 36 \times 4 \le 201144 回以下の操作で実現可能です。

後片付け・まとめ

 A1 A_1 A2 A_2 B B と関係ない値になっているので、操作 X \mathrm{X} を用いて合わせます。

 以上、平方分割→後片付けで目的を必ず達成できます (上の「簡単な場合分け」で排除した場合を除く)。

 時間計算量は O(N+P) O ( N + P ) 、操作回数は 2N+2P+O(logP) 2N + 2 \sqrt{P} + O( \log P ) です。

提出コード

提出コードのリンク:https://yukicoder.me/submissions/620527

 操作回数は

  • N=1 N=1 のとき高々 {(P1)/41}+1=55894 \{ (P-1)/4-1 \} + 1 = 55894
  • 2N 2 \le N のとき高々 105×2+500×2+36×8+2+1=201291 10^5 \times 2 + 500 \times 2 + 36 \times 8 + 2 + 1 = 201291

となり、 201291 201291 回以下です。

タイトルとURLをコピーしました