ABC242C別解: 行列による解法
ABC242C の別解
解答コード
提出_1: TLE.(N-1)回の行列の内積
提出_2: ギリAC.対称性を利用して行列サイズを小さくする
提出_3: AC.(N-1)回の内積を効率よく計算 <-本記事はこれ
解説
すでにDP(動的計画法)で求める方法は解説いたしました <リンク>.
今回のDPの計算を行列で表すと,
こんな行列になります.
実行してみると,もちろん前解説のdpを再現しています.
つまりこの問題は,Nが与えられたら,上の行列の(N-1)乗をして,上の行列の要素内の和を求めなさい.というように言い換えることができます.
しかし,行列の計算って遅いんです.
実際にすると提出_1のように,TLEになりました.
そこで,対称性を用いて計算量を減らすと,なんとかACになります(提出_2).
悩むこと一晩...
そしてついに,よくよく考えたら,行列のN乗を計算するときに,繰り返し自乗法で冪乗の計算の高速化と同様にすれば,早いじゃんっ!って気が付きました.
その関数がこちらです.正則行列をn乗します.途中でmodで割ります.ただそれだけです.
これを書けば,あとは単純です.入力の読み込みとMODを代入,初期の行列を定義して...
(N-1)乗を計算して,合計を出力します.
ライブラリのnumpyのndarrayで計算してますが,
もしかするとnumpyを使用しないで,
内積計算をpythonのリストとforで行えば,
多少処理が速くなるかもしれません.
以上,ABC242Cの別解でした.