Processing math: 70%

目次

AtCoder Beginner Contest 240 F,G問題メモ

AtCoder Beginner Contest 240

コンテストに参加してたら、数字が綺麗に並ぶ 2022/02/20 22:02:20 をうっかり見逃したので、ABC許さない(とばっちり)

F - Sum Sum Max

F - Sum Sum Max

問題

解法

i   0   1   2   3   4   5   6   7
C  -2  -2   4   4   4  -3  -3  -3
B  -2  -4   0   4   8   5   2  -1
A  -2  -6  -6  -2   6  11  13  12
                          ~~~~   ←最大値

A の最大値を求める上では、Bi と比べて Bi+1 が正なら次も足した方がいいし、負ならそこでひとまず止めた方がいい。

よって、数列の長さは非常に長くなりうるが、最大値をチェックするのは B が正から負に切り替わるタイミング(と、最初と最後)だけでよい。

それがいつ切り替わるかを直接求めるのは難しいが、B における N 個の xi,yi の切り替わり点を追っていけばわかる。

       j1          j2          j3
i   0   1   2   3   4   5   6   7
C  -2  -2   4   4   4  -3  -3  -3
B      -4           8          -1

切り替わり点の ij1,j2,... と表す。
Bjk は、単に xk×yk を累積的に足していけば求められる。
BjkBjk+1 を比べると、その中に A の最大値があり得るかどうかわかる。

正→負の区間だけチェックすればよいとわかった。

この中で切り替わる具体的な箇所 i を特定し、そこから最大値候補である Ai を求めたい。

切り替わり点から i が1つ進む毎に xk だけ減っていくので、Bjk1xk(切り捨て)だけ進んだ箇所が正、その次が負となる。

       j1          j2          j3
i   0   1   2   3   4   5   6   7
C  -2  -2   4   4   4  -3  -3  -3
B      -4           8→ 5→ 2→-1

              B[j2]/-x3 = 8/3 = 2 より、
              i=4 から 2 進んだ i=6 がこの区間の中で最大を取る箇所

前の区間の終わり i=4 から d=2 進んだ箇所が最大値をとるとわかったので、A6 を求める。

先頭から累積的に計算することで、Aj1,Aj2,... は計算できる。

       j1          j2          j3
i   0   1   2   3   4   5   6   7
C  -2  -2   4   4   4  -3  -3  -3
B      -4           8          -1
A      -6           6      []  12

1つ前の区間の終わりが Ar で、その次に C において n 個の xi が並んでいると、

と表現できる。

これを使うと、A6=A4+B4×d+d(d+1)2×x3=13 となり、正しく求められている。

正→負となる区間毎に調べていって、O(N) で全て求められる。

Python3

G - Teleporting Takahashi

G - Teleporting Takahashi

問題

解法

2次元なら、過去に類題があった(けどすっかり忘れてた)。

2次元の場合

N 回ちょうどで (0,0) から (X,Y) に移動する。

操作回数が最低限の |X|+|Y| に足りなかったり、偶奇が合わない場合は最初に除く。

最低限から余る移動回数については、 無駄な移動(同じ軸の正方向と負方向の移動のセット)を k=\dfrac{N-(|X|+|Y|)}{2} 回、しなくちゃいけない。

素直に考えると、x 軸方向で何回、y 軸方向で何回行うか決めれば計算できる。 片方の無駄を 0~k に固定して場合分けすればよい。 しかし、これだと O(k) かかる。

テクニックとして、45度回転させ、(+1,+1),(+1,-1),(-1,+1),(-1,-1) の4つの移動で (X+Y,X-Y) に到達する、と問題を言い換えると、 2つの軸を独立に考えることができ、2つの二項係数の積で O(1) で計算できてしまう。

3次元の場合

今回の制約では、単純に1次元の無駄回数を 0~k で固定して、2次元に帰着させるのを全通り試せばよい。

最初の階乗計算を除けば、全体 O(N) で求められる。

Python3