怠惰の累積和

技術/競プロ/怪文書/虚無

AtCoder Beginner Contest 134 D - Preparing Boxes

問題概要

 N個の箱が並んでおり、各箱にボールを入れるかどうかを決めることができる。この時、i(1≦i≦N)について、iの倍数が書かれた箱に入っているボールの数の総和を2で割った余りがa_iであるような入れ方を構成せよ。

atcoder.jp

 

解法

 箱を昇順に見て行こうとすると、i番目の箱にボールを入れるか否かを決めるためには、2*i,3*i,...番目の箱にボールが入っているかの情報が必要であるが、これはi番目の箱を見ている状態では未知の情報なのでこれではダメ。

 逆に、降順に見て行くと、昇順に見て行く時に未知であった情報は既に判明しているので箱を降順に見て行く方針で考える。

 これをしようとすると、

 ①:箱を降順に見て行く

 ②:①の内側のループで2*i,3*i,...番目の箱を見て行く

 というアルゴリズムになり、これはO(\frac{N}{1}+\frac{N}{2}+...\frac{N}{N})となり、間に合わなそうなお気持ちになるかもしれないが、

\frac{N}{1}+\frac{N}{2}+...\frac{N}{N}=N(\frac11+\frac12+...\frac1N)=N\displaystyle \sum_{i=1}^N \frac1i=N\displaystyle \int_1^N \frac1i di=NlogNとなるため、計算量はO(NlogN)となり、間に合う。

 間に合うため、上に書いたアルゴリズムを実装して、AC。

atcoder.jp