geam1113’s diary

主にAtcoderのコンテストの備忘録を書きます。AtCoder緑と水色を行ったり来たりしています。

ARC135 参加記録

コンテスト中AC:A,C
Bはコンテスト後自力AC。もう少しで解けそうでした。

A - Floor, Ceil - Decomposition

実際に10まで、xとfloor(x/2)×ceil(x/2)のどちらが大きいか手計算しました。

すると、

  • x≦4なら、x≧floor(x/2)×ceil(x/2)
  • x≧5なら、x<floor(x/2)×ceil(x/2)

となりました。大きめの数で試してもx<floor(x/2)×ceil(x/2)となり、その差は大きくなっていくので、厳密でないものの一般のxでもこれが成り立つと考えました。
よって、

  • x≦4ならそのまま、そうでなければfloor(x/2)とceil(x/2)に置き換える。

という解法が成り立つと考えました。

実装ですが、この手の問題ではメモ化再帰を使える場合が多いです。
メモ化することで、xが偶数なら状態は1/2になりますし、厳密ではないものの、全状態数は十分に少ないと見積もりました。
実際に提出してみると、ACできました。
(最大の1018くらいは試しておけばよかったです。)

厳密でなかった部分は、前者は公式解説に証明がありました。後者も証明できるそうです。(具体的な証明はありませんでした。) 提出コード

B - Sum of Three Terms

A_1,\ A_2及びS_iが決定すると、i\geq 3A_iを決定できます。
また、A_i \geq 0という制約があるので、A_1,\ A_2に関する何らかの制約が得られそうです。
A_7まで、列挙してみます。
A_1 = A_1
A_2 = A_2
A_3 = S_1 - A_1 - A_2
A_4 = S_2 - S_1 + A_1
A_5 = S_3 - S_2 +  A_2
A_6 = S_4 - S_3 + S_1 - A_1 - A_2
A_7 = S_5 - S_4 + S_2 - S_1 + A_1

S_iのみからなる定数部分をB_iとしておきます。B_iは、

i \leq 2のとき、B_i = 0
 i \geq 3のとき、B_i \leftarrow S_{i-1} - B_{i-1} - B_{i-2}

として、計算できます。

次に、A_1,\ A_2に関する制約式を得たいので、それぞれのA_iでの係数をA_1 [i],\ A_2 [i]とします。
これも以下のように計算できます。

i=1のとき、A_1 [1] = 1,\ A_2 [1] = 0
i=2のとき、A_1 [2] = 0,\ A_2 [1] = 1
i\geq 3のとき、
A_1 [i] = -A_1 [i-1]- A_1 [i-2]
A_2 [i] = -A_2 [i-1]- A_2 [i-2]

これを基に実際に実装して計算してみたところ、以下の事実に辿り着きました。

i\ mod\ 3 = 0のとき、A_1 [i] = -1,\ A_2 [i] = -1
i\ mod\ 3 = 1のとき、A_1 [i] = 1,\ A_2 [i] = 0
i\ mod\ 3 = 2のとき、A_1 [i] = 0,\ A_2 [i] = 1

そのため、A_i \geq 0という制約から、以下の3種類の制約式が得られます。

i\ mod\ 3 = 0のとき、A_1 + A_2  \leq B_i
i\ mod\ 3 = 1のとき、A_1 \geq -B_i
i\ mod\ 3 = 2のとき、A_2\geq -B_i

そこで、
A_1+A_2の上限をX
A_1の下限をY
A_2の下限をZ

とします。初め、X=S_1,\ Y=Z=0です。
これをi=3,4,...,N+2について、以下のように更新していきます。

i\ mod\ 3 = 0のとき、X\leftarrow  min(X,\ B_i)
i\ mod\ 3 = 1のとき、Y \leftarrow max(Y,\  -B_i)
i\ mod\ 3 = 2のとき、Z \leftarrow max(Z,\  -B_i)

これが終了したとき、
0\leq A_1 + A_2 \leq X
Y\leq A_1 \leq S_1
Z\leq A_2 \leq S_1
という制約式が得られ、これを満たすようなA_1,\ A_2を設定します。

まず、
X\lt 0
Y\gt S_1
 Z\gt S_1
のいずれかを満たす時、解なしです。

そうでないとき、
0\leq A_1 + A_2 \leq X
を満たすようにするには、A_1,\ A_2は、それぞれの下限であるA_1=YA_2 =Zにしておくのが最善です。
そのため、Y+Z\gt Xであれば解なしです。

そうでなければ、A_1=YA_2 =ZとしてAを構築できます。
(下記実装はiが0-indexedなので、i mod 3の値が異なっています) 提出コード

C - XOR to All

A=\{A_1,\ A_2,\ A_3,\ A_4,\ A_5\}として以下に一例を示します。

  1. A_1と全体のXORをとる。 \{A_1\oplus A_1,\ A_2\oplus A_1,\ A_3\oplus A_1,\ A_4\oplus A_1,\ A_5\oplus A_1\}

  2. A_5\oplus A_1と全体のXORをとる。
    \{A_1\oplus A_1\oplus A_5\oplus A_1,\ A_2\oplus A_1\oplus A_5\oplus A_1,\ A_3\oplus A_1 \oplus A_5\oplus A_1,\ A_4\oplus A_1\oplus A_5\oplus A_1,\ A_5\oplus A_1\oplus A_5\oplus A_1\}
    XORは交換法則が成り立ち、かつ、 X\oplus Y\oplus Y = X\oplus 0 = Xより、
    \{A_1\oplus A_5,\ A_2\oplus A_5,\ A_3\oplus A_5,\ A_4\oplus A_5,\ A_5\oplus A_5\}

これより、任意に置き換えを行った場合でも最終的には、
\{A_1\oplus A_i,\ A_2\oplus A_i,\ \cdots,\ A_N\oplus A_i\}
という形になります。

そこで、i=1,2,...,Nについて、
B_i=(A_1\oplus A_i)+(A_2\oplus A_i)+\cdots +(A_N\oplus A_i)
とした時、最大のB_iを求める問題と読み替えられます。

愚直にこれを計算するとO(N^2)となって、間に合わないため、工夫する必要があります。

ビットの問題では各ビットに着目するのが典型なので、それを基に考えてみます。すると、

  • A_ijビット目が0の場合、A_1,\  A_2,\ \cdots ,\ A_Njビット目はそのまま。
  • A_ijビット目が1の場合、A_1,\  A_2,\ \cdots ,\ A_Njビット目はすべて反転する。

ということがわかります。
そのため、A_1,\  A_2,\ \cdots ,\ A_Nのうち、jビット目が1の個数(または0の個数)さえ分かれば、以下のようにB_iを計算できます。

cnt_jA_1,\  A_2,\ \cdots ,\ A_Nの内、jビット目が1である要素の個数とし、
A_iの最大値A_{max}の最上位ビットをDビット目とする。

j=0,1,2,...,Dについて、

  • A_ijビット目が0の場合

    B_i2^jcnt_j個分足す:B_i \leftarrow B_i + cnt_j \times 2^j

  • A_ijビット目が1の場合

    B_i2^jN-cnt_j個分足す。:B_i \leftarrow B_i + (N-cnt_j) \times 2^j

このようにすると、全てのB_iO(DN)で計算できます。 A_i \lt 2^{30}という制約上、Dは最大で29なので、jのループは最大でも30回となり、余裕を持って間に合います。

なお、操作を一度も行っていない場合も考慮する必要があります。

提出コード