AGC028-B: Removing Blocks

数え上げ力の不足。

問題概要

1からNまでの番号がついたブロックが横にならんでおり,ブロックiには重さA_iがある。ここからN回ブロックを取り除くのだが,ブロックiを取り除くコストはブロックiと連結な(自身も含む)ブロックの重みの総和である。取り除く順番はN!通りあるが,それらのコストの総和を求めよ。

問題リンク:

B - Removing Blocks

解法

この手の問題は,「A_iが何回加算されるか?」ということを考えるのが定石である(そこまではわかる,という人が多かったと思う)。特にこの場合は,「ブロックjを取り除いたときにA_iが加算されるのは何回か?」ということを考えればよい。各jについてこれを足し合わせれば「A_iが何回加算されるか?」という問いの答えがわかる(ここまではよかった)。

では,「ブロックjを取り除いたときにA_iが加算されるのは何回か?」という問いを考えよう。簡単のため,j\leq iとする。公式解説では確率を用いているが(これはこれで賢い),実は確率を持ち出さなくても十分である。ブロックjを取り除いたときにA_iが加算されるためには,ブロックjを取り除くまでに,ブロックjからブロックiまでが取り除かれなければよい。そのような順列はいくつあるかを考える。
i-j+1=kとおこう。これらjからik個の数の並べ方のうち,jが一番最初になるのはもちろん(k-1)!通りである。これを1からNの順列に埋め込むことを考える。埋め込む位置の選び方は,N箇所からk箇所選ぶ場合の数なので,{}_N \mathrm{C} _k通りである。jからi以外の数字の並べ方は任意でよいので,(N-k)!通りある。以上より,「ブロックjを取り除いたときにA_iが加算されるのは何回か?」という問いの答えは,(k-1)! \times {}_N \mathrm{C} _k \times (N-k)! = \frac{N!}{k}とわかった。
i \lt jのときも同様に考えて同じ表式を得る。あとは,\frac{1}{k}の累積和を事前に計算すれば,「A_iが何回加算されるか?」という問いにO(1)で答えることができる。よって,全体でO(N)で計算ができる。

提出


Submission #3403177 - AtCoder Grand Contest 028


これが解けなかったのは悲しい。