羅区P3390 [テンプレート]行列高速電力
説明
- 与えられたn個の* nの行列A、A ^ kが求め
- N <= 100、K <= 10 ^ 12、|行列要素| <= 1000
入力
最初の行、N、K
N + 1は、第二の列に、各列数n、iは、+ 1番目の行及びjはi及び列jマトリクス行の要素の数を表します
出力
A ^ kの出力
n行の合計、それぞれ行数n、i番目の行及びjはマトリクス行j列、モールド10 ^ 7 + 9の各要素のi番目の要素の数を表します。
サンプル入力
2 1
1 1
1 1
サンプル出力
1 1
1 1
ソリューション:
タイトルに示されているようなアルゴリズム。
どのような行列でありますか?
- それは、マトリックス、文字通りの意味です。
どのように行列演算?
- さらに2つの場合のような形状の和に対応する位置のような行列、
- 減算:添加と同様に
- 部門:実際にはそこにあるように見えますが、一般的にOIで使用されていない、説明しません。
- 乗算は:行列の乗算がハイライトされ、彼女は前提条件を持っていた、二つの行列の乗算は、(N、M)を満たさなければならない*(M 、P)=(N、P)。(前列の数が列であり、数)。このような↓(2、2)*( 2、1)=(2,1)
\ [\左\ {\開始{行列} 1&1 \\ 0端{行列} \ 3 \\ \右\} * \左\ {\開始{行列}端\ 2 \\ 2 \\ {マトリックス} \右\} = \左\ {\開始{行列}端{行列} \ 1 * 2 + 1 * 2 \\ 0 * 2 + 3 * 2 \\ \右\} \]
\ [\左[\始める右{行列}端{行列} \ 2 \\ 2 \\ \] * \左[\ {行列} 1&1 \\ 0端\ 3 \\ {行列}開始\右]!= \ [\右\端{行列} \ {行列} 1 * 2 + 1 * 2 \\ 0 * 2 + 3 * 2 \\始める]書くことが間違っている左!\]
(2、1)*(2、2)ので。1!= 2、意義の行列乗算を満たしていません。
- また、それを起動することができます。行列は可換ではありません
マトリックスの使用は何ですか?
- 再帰の最適化。
- 再帰を最適化する際にどのように私は知っていますか?
- データの大きな範囲をそのような18のどの電源として、O(N)10は、硬質です
- どのように最適化するには?
- 一般的な最適化は、マトリックス、高速にパワーを最適化することですが、どのように高速な最適化電源を書き込んだ後、電源を入れ、ここで
- だから今の作業は行列にすばやく電源を書くことです!
高速マトリックスミ:
- まず、行列の乗算は、連想され得ることは容易である、非常に高速のパワーフォームは、コードが直接、それを味わう与え、速いの通常のパワーと違いはありません。(とにかく、私はあなたが理解についての記事を読みます)
#include <iostream> #include <cstdio> #define maxn 105 #define mod 1000000007 #define LL long long using namespace std; struct Obj {LL a[maxn][maxn];} x, d; LL n, p; Obj mul(Obj x, Obj y) { Obj r; for(LL i = 1; i <= n; i++) for(LL j = 1; j <= n; j++) r.a[i][j] = 0; for(LL i = 1; i <= n; i++) for(LL j = 1; j <= n; j++) for(LL k = 1; k <= n; k++) r.a[i][j] += (x.a[i][k] % mod * y.a[k][j] % mod) % mod, r.a[i][j] %= mod; return r; } Obj power(Obj x, LL p) { Obj r = d, base = x; while(p) { if(p & 1) r = mul(r, base); base = mul(base, base); p >>= 1; } return r; } int main() { cin >> n >> p; for(LL i = 1; i <= n; i++) for(LL j = 1; j <= n; j++) cin >> x.a[i][j]; for(LL i = 1; i <= n; i++) d.a[i][i] = 1; Obj ans = power(x, p); for(LL i = 1; i <= n; i++) { for(LL j = 1; j <= n; j++) cout << ans.a[i][j] % mod << ' '; cout << endl; } return 0; }