目次

NOMURA プログラミングコンテスト2022(AtCoder Beginner Contest 253)F問題メモ

NOMURA プログラミングコンテスト2022(AtCoder Beginner Contest 253)

久々の7完。気持ち、中盤の問題に典型が多めだった?

F - Operations on a Matrix

F - Operations on a Matrix

問題

解法

クエリ3が来たとき、「そのマスが最後にクエリ2で上書きされた時の $x$ に、それより後にクエリ1で加算された値を全て加えた値」を出さないといけない。

あるマスに対するクエリの履歴例(q1:加算、q2:上書き更新)

q1(1) q1(3) q2(5) q1(7) q2(9) q1(2) q1(4)  q3 この時の値は?
                        ~~~~~~~~~~~~~~~~~     →ここの合計

クエリ1は、まぁ範囲加算と1点取得なので、Fenwick木なんかで管理することになるだろう。
ただ、「$j$ 列目に対する加算のうち、あるタイミングより後の加算のみを取り出す」ことを、クエリ3の時点でやろうとすると難しい。

クエリ2で上書きされた時に、その時点の列の累積加算値を記録しておけば、クエリ3が来た時点の累積加算値との差分で、クエリ1による加算値は求められる。

            q1(1) q1(3) q2(5) q1(7) q2(9) q1(2) q1(4)  q3
累積加算値     1     4          11          13    17
                                      *                    この時に現在の値 11 を記録
                                                       *   この時の現在の値 17 との差分 6 が、
                                                            最後のクエリ2以降に加算された値

だが、クエリ2が来るたびに全ての列に対して現在値を記録しておく訳にもいかないので、本当に必要な列、 つまり「そのクエリ2で上書きされた値 $x$ を使うようなクエリ3の列」を先読みして、そこのみ記録しておく、といった処理をする必要がある。

まぁ実際にその通りやってもいいんだけど、クエリを逆順に考えると、多少は見通しが良くなる。

クエリ3で記録して、クエリ2で確定、となるので、どの列に対して記録しなければならないかがクエリ順的にわかりやすくなる。

Python3