CODE FESTIVAL 2016 qual C E 順列辞書

問題

atcoder.jp

考察

まずは、部分問題を考えます。
 p_1\ldots p_nの中に0が含まれない場合の答えを計算してみます。
これは、 \sum_{i=1}^N (N-i)! \times |\{j|j > i,p_j < p_i\}|であることが確認できます。

そこで、一般の場合は、
各x,yに対し、
C_{x,y}: |\{j|j > x,p_j < p_x \}|=yとなる順列の数
とおき、 \sum_{x,y}^N (N-i)!*y*C_{x,y}を計算すればよいです。

これだとO(N^2)ですが、さらにC_{x,y}*yに注目して、
D_x:j > x,p_j < p_xなるjの数を全ての順列について足しあげたもの
とおいて、 \sum_{x,y} (N-i)!*y * D_xを計算すればよいです。

これで勝ったも同然で、p_x,p_jが0か0でないかで4通りに場合分けし、それぞれきちきち計算すればD_xは高速に計算できるので、答えが求まります。
実装は場合分けが多いのでやや大変でした・・・

感想

ひと月ほどまえ考えた際には歯が立たなかったのですが、いま考えたらすんなりいったのでよかったです。
まずは、0が含まれない場合を計算して、それらの和を別方向からみて足し上げるのが鍵でした。

提出コード

atcoder.jp