No.025 D

の場合を考える.

DP で考えると, 列にはコンセントを刺さない/刺すの2パターンある. ここで言うコンセントを刺すとは, 列目に左側のプラグを刺すことを表す. 以下も同様である.

このときの組み合わせの数の列を とすると, を使って と表すことができる.

ここで, 列目と 列目のコンセントキャップ (以下キャップ) の状態に依存する. 列目と 列目にキャップがない状態の場合は,

となり, 行目を とすると, キャップの状態によって次のようになる.

  • はキャップの状態の影響を受けない.
  • 列目か 列目にキャップがあれば となる.

なお, 列目には常にキャップがあると考える.

次に の場合を考える.

の場合と同様に, 列にはコンセントを刺さない/縦に刺す/1行目だけ横に刺す/2行目だけ横に刺す/1,2行目に横に刺すの5パターンがある.

このときの組み合わせの数の列を とすると, を使って と表すことができる.

ここで, 列目と 列目のキャップの状態に依存する. 列目と 列目にキャップがない状態の場合は,

となり, 行目を とすると, キャップの状態によって次のようになる.

  • はキャップの状態の影響を受けない.
  • 列目にキャップがあれば となる.
  • は1行目の 列か 列にキャップがあれば となる.
  • は2行目の 列か 列にキャップがあれば となる.
  • 列か 列にキャップがあれば となる.

どちらの場合も行列の総乗を計算するセグメントツリーにキャップがない状態の行列を入れておき, クエリごとにこれを更新して組み合わせの数を求める.

部分点2はこの方法で可能だが, 満点は がかなり大きいためもうひと工夫が必要となる.

そこでクエリを先読みして座標圧縮をする. キャップはその前の列までしか影響を与えないので, キャップの影響を受けない列はひとまとめにできる.

行列をひとまとめにするには繰り返し二乗法が使える.