zoukankan      html  css  js  c++  java
  • 矩阵快速幂总结

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

    快速幂:

    #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("
    ");
        }
        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("
    "))
        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 守望者的烦恼

    总结:

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

  • 相关阅读:
    为什么要有binary-to-text encoding?
    海量网络存储系统原理与设计(三)
    Java中的Inner Class (一)
    海量网络存储系统原理与设计(二)
    海量网络存储系统原理与设计(一)
    [JavaScript]顺序的异步执行
    [PAT]素因子分解(20)
    [PAT]求集合数据的均方差(15)
    [PAT]数列求和(20)
    【C-001】printf理解
  • 原文地址:https://www.cnblogs.com/12fs/p/7789014.html
Copyright © 2011-2022 走看看