• HDU 5015 233 Matrix --矩阵快速幂


    题意:给出矩阵的第0行(233,2333,23333,...)和第0列a1,a2,...an(n<=10,m<=10^9),给出式子: A[i][j] = A[i-1][j] + A[i][j-1],要求A[n][m]。

    解法:看到n<=10和m<=10^9 应该对矩阵有些想法,现在我们假设要求A[a][b],则A[a][b] = A[a][b-1] + A[a-1][b] = A[a][b-1] + A[a-1][b-1] + A[a-2][b] = ...

    这样相当于右图:,红色部分为绿色部分之和,而顶上的绿色部分很好求,左边的绿色部分(最多10个)其实就是:A[1][m-1],A[2][m-1]..A[n][m-1],即对每个1<=i<=n, A[i][m]都可由A[1][m-1],A[2][m-1]..A[n][m-1],于是建立12*12的矩阵:

    ,将中间矩阵求m-1次幂,与右边[A[0][1],A[1][1]..A[n][1],3]^T相乘,结果就可以得出了。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define Mod 10000007
    #define SMod Mod
    #define lll __int64
    using namespace std;
    
    int n,m;
    lll a[100006],sum[100005];
    
    struct Matrix
    {
        lll m[13][13];
        Matrix()
        {
            memset(m,0,sizeof(m));
            for(int i=1;i<=n+2;i++)
                m[i][i] = 1LL;
        }
    };
    
    Matrix Mul(Matrix a,Matrix b)
    {
        Matrix res;
        int i,j,k;
        for(i=1;i<=n+2;i++)
        {
            for(j=1;j<=n+2;j++)
            {
                res.m[i][j] = 0;
                for(k=1;k<=n+2;k++)
                    res.m[i][j] = (res.m[i][j]+(a.m[i][k]*b.m[k][j])%SMod + SMod)%SMod;
            }
        }
        return res;
    }
    
    Matrix fastm(Matrix a,int b)
    {
        Matrix res;
        while(b)
        {
            if(b&1)
                res = Mul(res,a);
            a = Mul(a,a);
            b >>= 1;
        }
        return res;
    }
    
    int main()
    {
        int i,j;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            sum[0] = 0;
            for(i=1;i<=n;i++)
            {
                scanf("%I64d",&a[i]);
                sum[i] = (sum[i-1] + a[i]);
            }
            lll suma = sum[n];
            if(m == 1)
            {
                printf("%I64d
    ",(233LL+suma)%Mod);
                continue;
            }
            Matrix base;
            memset(base.m,0,sizeof(base.m));
            for(i=1;i<=n+1;i++)
                base.m[i][1] = 10LL;
            for(i=2;i<=n+1;i++)
            {
                for(j=2;j<=n+1;j++)
                {
                    if(i >= j)
                        base.m[i][j] = 1LL;
                }
            }
            for(i=1;i<=n+2;i++)
                base.m[i][n+2] = 1LL;
            Matrix Right;
            memset(Right.m,0,sizeof(Right.m));
            Right.m[1][1] = 233LL;
            for(i=2;i<=n+1;i++)
                Right.m[i][1] = (233LL+sum[i-1])%Mod;
            Right.m[n+2][1] = 3LL;
            Matrix ans = fastm(base,m-1);
            ans = Mul(ans,Right);
            printf("%I64d
    ",ans.m[n+1][1]%Mod);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    以太坊:用 Solidity 写测试用例
    以太坊:测试合约
    以太坊:支持 Quorum 开发
    以太坊:编写外部脚本
    以太坊:使用控制台
    以太坊:调试合约
    Rancher 2.x 搭建及管理 Kubernetes 集群
    我的友情链接
    我的友情链接
    我的友情链接
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3971994.html
Copyright © 2020-2023  润新知