hdu 5015——233 Matrix

35 篇文章 0 订阅

题意:矩阵的第一行是233,2333,23333……,第一列输入,矩阵每个位置满足ai,j = ai-1,j +ai,j-1( i,j ≠ 0),求矩阵的最左下角的元素

思路:矩阵快速幂

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

typedef long long ll;
const ll mod=10000007;
const int maxn=20;

struct Matrix{
    int n,m;
    ll a[maxn][maxn];
    void clear(){
        n=m=0;
        memset(a,0,sizeof(a));
    }

    Matrix operator + (const Matrix &b) const{
        Matrix tmp;
        tmp.n=n;
        tmp.m=m;
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<m;++j)
            {
                tmp.a[i][j]=a[i][j]+b.a[i][j];
                tmp.a[i][j]%=mod;
            }
        }
        return tmp;
    }
    Matrix operator - (const Matrix &b) const{
        Matrix tmp;
        tmp.n=n;
        tmp.m=m;
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<m;++j)
            {
                tmp.a[i][j]=a[i][j]-b.a[i][j];
            }
        }
        return tmp;
    }
    Matrix operator * (const Matrix &b) const{
        Matrix tmp;
        tmp.clear();
        tmp.n=n;
        tmp.m=b.m;
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<b.m;++j)
            {
                for(int k=0;k<m;++k){tmp.a[i][j]+=a[i][k]*b.a[k][j];tmp.a[i][j]%=mod;}
            }
        }
        return tmp;
    }
};

Matrix fast_pow(Matrix a,int n)
{
    Matrix ret;
    ret.clear();
    ret.n=a.n;
    ret.m=a.m;
    for(int i=0;i<ret.n;++i)
    {
        ret.a[i][i]=1;
    }
    while(n)
    {
        if(n&1)
        {
            ret=ret*a;
        }
        a=a*a;
        n>>=1;
    }
    return ret;
}

int main()
{
//    freopen("data.txt","r",stdin);
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        m++;
        n++;
        Matrix ans;
        ans.n=n+1;
        ans.m=1;
        for(int i=1;i<n;++i)
        {
            scanf("%I64d",&ans.a[i][0]);
        }
        ans.a[0][0]=233;
        ans.a[n][0]=3;
        Matrix mul;
        mul.clear();
        mul.n=n+1;
        mul.m=n+1;
        mul.a[0][0]=10;
        mul.a[0][n]=1;
        for(int i=1;i<mul.n-1;++i)
        {
            for(int j=0;j<=i;++j)mul.a[i][j]=1;
        }
        mul.a[n][n]=1;
        mul=fast_pow(mul,m-1);
        ans=mul*ans;
        printf("%I64d\n",ans.a[n-1][0]);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值