No.025 D
の場合を考える.
DP で考えると, 列にはコンセントを刺さない/刺すの2パターンある. ここで言うコンセントを刺すとは, 列目に左側のプラグを刺すことを表す. 以下も同様である.
このときの組み合わせの数の列を とすると, は を使って と表すことができる.
ここで, は 列目と 列目のコンセントキャップ (以下キャップ) の状態に依存する. 列目と 列目にキャップがない状態の場合は,
となり, の 行目を とすると, キャップの状態によって次のようになる.
- はキャップの状態の影響を受けない.
- は 列目か 列目にキャップがあれば となる.
なお, 列目には常にキャップがあると考える.
次に の場合を考える.
の場合と同様に, 列にはコンセントを刺さない/縦に刺す/1行目だけ横に刺す/2行目だけ横に刺す/1,2行目に横に刺すの5パターンがある.
このときの組み合わせの数の列を とすると, は を使って と表すことができる.
ここで, は 列目と 列目のキャップの状態に依存する. 列目と 列目にキャップがない状態の場合は,
となり, の 行目を とすると, キャップの状態によって次のようになる.
- はキャップの状態の影響を受けない.
- は 列目にキャップがあれば となる.
- は1行目の 列か 列にキャップがあれば となる.
- は2行目の 列か 列にキャップがあれば となる.
- は 列か 列にキャップがあれば となる.
どちらの場合も行列の総乗を計算するセグメントツリーにキャップがない状態の行列を入れておき, クエリごとにこれを更新して組み合わせの数を求める.
部分点2はこの方法で可能だが, 満点は がかなり大きいためもうひと工夫が必要となる.
そこでクエリを先読みして座標圧縮をする. キャップはその前の列までしか影響を与えないので, キャップの影響を受けない列はひとまとめにできる.
行列をひとまとめにするには繰り返し二乗法が使える.