luogu3390 矩阵快速幂

  矩阵A乘矩阵B是A的第i行向量乘以B的第j列向量的值放在结果矩阵的i行j列。因为矩阵乘法满足结合律,所以它可以与一般的快速幂算法同理使用。注意矩阵在乘的时候取模。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define ll long long

const int MAX_N = 110;
const ll P = 1e9 + 7;

struct Matrix
{
    ll A[MAX_N][MAX_N];
    int N;
    
    Matrix(int n)
    {
        N = n;
        memset(A, 0, sizeof(A));
    }
    
    void operator = (const Matrix& a)
    {
        memcpy(A, a.A, sizeof(a.A));
        N = a.N;
    }
    
    void operator *= (const Matrix& a)
    {
        Matrix ans(N);
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
                for (int k = 1; k <= N; k++)
                    ans.A[i][j] += (A[i][k] % P) * (a.A[k][j] % P) % P;
        *this = ans;
    }
    
    void operator %= (const ll x)
    {
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
                A[i][j] %= x;
    }
    
    void SetAnsUnit()
    {
        memset(A, 0, sizeof(A));
        for (int i = 1; i <= N; i++)
            A[i][i] = 1;
    }
    
    bool Empty()
    {
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
                if (A[i][j])
                    return false;
        return true;
    }
    
    void Print()
    {
        for (int i = 1; i <= N; i++)
        {
            for (int j = 1; j <= N; j++)
                printf("%lld ", A[i][j]);
            printf("\n");
        }
    }
};

Matrix Power(Matrix a, ll n)
{
    Matrix ans(a.N);
    ans.SetAnsUnit();
    while (n)
    {
        if (n & 1)
        {
            ans *= a;
            ans %= P;
        }
        a *= a;
        a %= P;
        n >>= 1;
    }
    return ans;
}

int main()
{
    int n;
    long long k;
    scanf("%d%lld", &n, &k);
    static Matrix a(n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            scanf("%d", &a.A[i][j]);
    Power(a, k).Print();
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/headboy2002/p/9362888.html
今日推荐