码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵快速幂

时间:2018-10-10 14:33:29      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:bsp   div   style   operator   stream   规划   快速   namespace   void   

将线性递推式转化成矩阵乘法,再结合快速幂实现O(logn)

此法可广泛用于动态规划等递推题目

实现时仅需将*重载,其余同快速幂

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
const ll p=1e9+7;
ll n,k;
struct Z{
    ll a[105][105];
    Z operator * (const Z w) const
    {
        Z re;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                re.a[i][j]=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++)
                    re.a[i][k]+=a[i][j]*w.a[j][k],
                    re.a[i][k]=re.a[i][k]%p;
        return re;
    }
};
Z s,e;
void Read(ll &x);
void Write(ll x);
Z power(Z w,ll kk)
{
    Z re=e;
    while(kk>0)
    {
        if(kk&1) re=re*w;
        w=w*w;
        kk>>=1;
    }
    return re;
}
int main()
{
    Read(n),Read(k);
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=n;j++)
            Read(s.a[i][j]),e.a[i][j]=0;
    for(int i=1;i<=n;i++) e.a[i][i]=1;
    Z w=power(s,k);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++) Write(w.a[i][j]%p),putchar( );
        putchar(\n);
    }
    return 0;
}
void Read(ll &x)
{
    ll i=1;
    x=0;
    char c=getchar();
    while(c<0 or c>9)
    {
        if(c==-) i=-1;
        c=getchar();
    }
    while(c>=0 and c<=9)
    {
        x=x*10+(c-0);
        c=getchar();
    }
    x*=i;
}
void Write(ll x)
{
    if(x<0) 
    {
        putchar(-);
        x=-1*x;
    }
    if(x>9) Write(x/10);
    putchar(x%10+0);
}

 

矩阵快速幂

标签:bsp   div   style   operator   stream   规划   快速   namespace   void   

原文地址:https://www.cnblogs.com/shzyk/p/9765692.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!