F - Predilection Editorial by kyopro_friends


\(A\) の累積和を \(A'\) とします。すなわち、 \(1\leq i \leq N\) に対し \(A'_i = \sum_{k=1}^{i}A_k\) とします。

操作後の数列を \(B\)とし、その累積和を \(B'\) とします。\(B\)\(B'\) は1対1に対応するので、相異なる \(B'\) の個数を求めればよいです。
\(A\) に対する操作は、\(A'\) においては「数列の末尾以外の要素を \(1\) つ取り除く」ことと対応します。したがって、\(B'\) としてありえるものは「\(A'\) の部分列であって、『\(A'\) の末尾の要素』を末尾にもつもの」となります。そのようなものの個数は「\(A'\) から末尾の要素を除いた長さ \(N-1\) の数列の(空列を含む)部分列の個数」に等しくなるため、部分列DPにより求めることができます。

部分列DPの参考資料:Qiita『部分列 DP — 文字列の部分文字列を重複なく走査する DP の特集』(drken)
https://qiita.com/drken/items/a207e5ae3ea2cf17f4bd
なお、この記事で紹介されている実装は、数列に登場する値の種類数を \(\sigma\) として \(\Theta(\sigma N)\) ですが、この問題では \(\sigma=\Theta(N)\) となるケースが存在するため、この実装をそのまま使うことはできません。適切に累積和を使うことで \(O(\sigma+N)\) にすることができます。考えてみましょう

posted:
last update: