P3390 【模板】矩阵快速幂

题目背景

矩阵快速幂

题目描述

给定n*n的矩阵A,求A^k

输入输出格式

输入格式:

 

第一行,n,k

第2至n+1行,每行n个数,第i+1行第j个数表示矩阵第i行第j列的元素

 

输出格式:

 

输出A^k

共n行,每行n个数,第i行第j个数表示矩阵第i行第j列的元素,每个元素模10^9+7

 

输入输出样例

输入样例#1:
2 1
1 1
1 1
输出样例#1:
1 1
1 1

说明

n<=100, k<=10^12, |矩阵元素|<=1000 算法:矩阵快速幂


如题,矩阵快速幂。

已知,矩阵乘法:

第一个矩阵:

5 6 7

8 9 4

第二个矩阵:

2 3 7

2 4 8

8 3 6

相乘得:

5*2+6*2+7*8  5*3+6*4+7*3  5*7+6*8+7*6

8*2+9*2+4*8  8*3+9*4+4*3  8*7+9*8+4*6

即:

78  60  125

36  72  152

再利用快速幂可得答案。

 最后附上经我们喻队(

PIPIBoss

)指点的代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#define ll long long
using namespace std;
ll read()
{
    ll x=0,y=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            y=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*y;
}
int n;
ll k;
struct ju
{
    ll a[145][145];
    inline ju operator *(const ju &b)const//inline用来定义内联函数,即在类中用的函数,可以加快速度。
    {                      //该函数的作用是来重载*号运算符。
        ju tmp;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                tmp.a[i][j]=0;
                for(int k=1; k<=n; k++)
                {
                    tmp.a[i][j]+=a[i][k]*b.a[k][j];
                    tmp.a[i][j]%=1000000007;
                }
            }
        return tmp;
    }
}ans;
ju pow(ju a,ll k)
{
    ju tmp=a;
    k--;
    while(k)
    {
        if(k&1)
            tmp=tmp*a;
        a=a*a;
        k>>=1;
    }
    return tmp;
}
int main()
{
    scanf("%d%lld",&n,&k);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            ans.a[i][j]=read();
    ans=pow(ans,k);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
            printf("%lld ",ans.a[i][j]);
        putchar('\n');
    }
    return 0;
}

//    FOR C.H.

 

最后的最后,别忘了加上头文件,我一开始就是因为没加头文件错了几次。

posted @ 2017-07-07 21:39  GSHDYJZ  阅读(159)  评论(0编辑  收藏  举报