羅区P3390 [テンプレート]行列高速電力

羅区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

ソリューション:

  • タイトルに示されているようなアルゴリズム。

  • どのような行列でありますか?

    • それは、マトリックス、文字通りの意味です。
  • どのように行列演算?

    1. さらに2つの場合のような形状の和に対応する位置のような行列、
    2. 減算:添加と同様に
    3. 部門:実際にはそこにあるように見えますが、一般的にOIで使用されていない、説明しません。
    4. 乗算は:行列の乗算がハイライトされ、彼女は前提条件を持っていた、二つの行列の乗算は、(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;
    }

おすすめ

転載: www.cnblogs.com/BigYellowDog/p/11203363.html