AGC036-C GP 2
細部が詰められなかったので解説の方法でACしてしまったが、あとで落ち着いて詰め直したらできた。 自分の解法は解説の方法より(実装は面倒だが)直感的だと思うので、紹介しておく。
問題概要
長さ の数列があって、異なる2要素を選んでそれぞれ1と2を足す、という操作を 回行う。操作のあとの数列としてありうるものは何通りあるか、 で求めよ。
考察
DPで通せそうな制約でもないので、必要条件・十分条件を列挙して数え上げを考える。 次の3つが必要十分条件となる。
- 数列の総和が であること
- 数列の最大値が 以下であること
- 数列のうち、奇数は 個以下であること
証明は省くが、やってみると明らかそうなので本番なら無証明で通せそうな感じはある。
さて、これを満たす数列を数え上げるわけだが、解説では次のように行っていた。
奇数が 個の場合、まず最大値を考えないと 個ある。
ここからある要素が を超えるものを除きたいが、総和を考えればこのような要素は高々ひとつなので、このような要素の場所を固定すれば、総和 , 長さ で、その要素が を超えるような数列の数と対応する。このような数列の数は、前と同じ問題を と について解いて差をとれば求まるので、この問題が解けた。
この解法は実装が簡単だが、発想がちょっと難しい。(と自分は思った。)
自分の考えた解法は次のようである。
と の塊が複数個あり、これを振り分けていくという発想をする。 の塊は当然 個以上 個以下であり、 と偶奇は一致する。ここで、 の塊の数を 個とおく。
まず、 の要素を含むか含まないかで場合分けをする。
を含む場合、残りの 個から集合を選んでそれに を足し、残った の塊を適当に振り分ける、という操作だと考えると、このような通り数は となる。
を含まない場合、 の塊の振り分け方 個から、 以上の要素を含む場合を除き、 の塊の振り分け方 を掛ければよい。
以上の要素を含む場合の数は、1要素固定すれば 通りだとわかるので、累積和などを用いて高速化でき、この問題が解けた。