矩阵快速幂总结

基础:快速幂,矩阵乘法;

快速幂:

#include<cstdio>
#include<cstring>
#define ll long long
ll poww(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans*=a;
        b>>=1;a*=a;
    }
    return ans;
}
int main()
{
    ll a,b;
    scanf("%lld %lld",&a,&b);
    ll ans=poww(a,b);
    printf("%lld",ans);
    return 0;
}
快速幂

矩阵乘法:

#include<cstdio>
#include<cstring>
const int N=112;
int m1[N][N],m2[N][N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int t=1;t<=2;t++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    if(t==1) scanf("%d",&m1[i][j]);
    else scanf("%d",&m2[i][j]);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int ans=0;
            for(int k=1;k<=n;k++)
            {
                ans+=m1[i][k]*m2[k][j];
            }
            printf("%d ",ans);
        }
        printf("\n");
    }
    return 0;
}
矩阵乘法

矩阵快速幂:

将二者结合就是矩阵快速幂;

#include<cstdio>
#include<cstring>
const int N=112;
int res[N][N],tt[N][N];
int n,m;
const int mod=1e9+7;  
inline void matrix(int a[N][N],int b[N][N])
{
    memset(tt,0,sizeof(tt));
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    for(int k=1;k<=n;k++)
    tt[i][j]=( tt[i][j]+(long long)a[i][k]*b[k][j]%mod)%mod;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    a[i][j]=tt[i][j];    
}
int a[N][N];
void j_poww(int b)
{
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    scanf("%d",&a[i][j]);
    memset(res,0,sizeof(res));
    for(int i=1;i<=n;i++) res[i][i]=1;
    while(b)
    {
        if(b&1) matrix(res,a);
        b>>=1;    
        matrix(a,a)    ;
    }
}
int main()
{
    scanf("%d %d",&n,&m);
    j_poww(m);
    for(int i=1;i<=n;i++,printf("\n"))
    for(int j=1;j<=n;j++)
    printf("%d ",res[i][j]);    
    return 0;
}
矩阵快速幂

运用:

一:51nod 1013 3的幂的和可以用矩乘(也可以用公式)

二:vijos Warcraft III 守望者的烦恼:矩乘

#include<cstdio>
#include<cstring>
#define ll long long 
const int N=12,mod=7777777;
int k,n;
ll f[N];
int min(int a,int b)
{
    if(a>b) return b;
    else return a;
}
typedef long long matrix [N][N];
inline void calc(matrix a,matrix b)
{
    matrix c;
    memset(c,0,sizeof(c));
    for(int i=1;i<=k;i++)
    for(int j=1;j<=k;j++)
    for(int l=1;l<=k;l++)
    c[i][j]=(c[i][j]+a[i][l]*b[l][j])%mod;
    for(int i=1;i<=k;i++)
    for(int j=1;j<=k;j++)
    a[i][j]=c[i][j];
}
matrix ans,a;
long long b[N];
ll poww(int n)
{
    for(int i=1;i<=k;i++) ans[i][i]=1;
    for(int i=2;i<=k;i++) a[i-1][i]=1;
    for(int i=1;i<=k;i++) a[k][i]=1;
    for(int i=k;i>=1;i--)  b[k-i+1]=f[k+1-i];   
//    for(int i=1;i<=k;i++) b[i]=f[i-1];
    while(n)
    {
        if(n&1) calc(ans,a);
        n>>=1;
        calc(a,a);
    }
    ll sum=0;
    for(int i=1;i<=k;i++)
    sum=(sum+ans[k][i]*b[i]%mod)%mod;
    return sum;
}
int main()
{
    scanf("%d %d",&k,&n);
    f[0]=1;
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=i;j++)
            f[i]=(f[i]+f[i-j])%mod;
    }
//    for(int i=1;i<=10;i++) printf("%d ",f[i]);
     if(n<=k) printf("%lld",f[n]);    
    else printf("%lld",poww(n-k));
    return 0;
} 
Warcraft III 守望者的烦恼

总结:

基础与代码都不难,关键是构建矩阵(多做点题)

posted @ 2017-11-05 22:00  12fs  阅读(201)  评论(0编辑  收藏  举报