B - 233 Matrix(矩阵快速幂)

In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 ... in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be 233, 2333, 23333... (it means a 0,1 = 233,a 0,2 = 2333,a 0,3 = 23333...) Besides, in 233 matrix, we got a i,j = a i-1,j +a i,j-1( i,j ≠ 0). Now you have known a 1,0,a 2,0,...,a n,0, could you tell me a n,m in the 233 matrix?

Input

There are multiple test cases. Please process till EOF.

For each case, the first line contains two postive integers n,m(n ≤ 10,m ≤ 10 9). The second line contains n integers, a 1,0,a 2,0,...,a n,0(0 ≤ a i,0 < 2 31).

Output

For each case, output a n,m mod 10000007.

Sample Input

1 1
1
2 2
0 0
3 7
23 47 16

Sample Output

234
2799
72937


        
  

Hint

 


题解:该矩阵第一行除了第一个元素为0以外,有后一个是前一个*10+3=的结果规律,即b[1][i+1]=b[1][i]*10+3.

对于Case 2::我们构造n+2级规律矩阵a=      

10   0   0    1

10   1   0    1

10   1   1    1

 0    0   0    1

并将b补齐为方阵,b数组即为最后数组的第一列,此时将第一个数为了规律要求改为23,并增加1级。

23  0   0    0

x1  0    0    0

x2  0    0    0

3    0    0    0

我们做第x次乘法所得的矩阵的第一列就是最后矩阵的第x+1列。

做m次乘法展开为res=a*a*a*...*b;则res中第1列即为最后矩阵的第m+1列

则可进行矩阵幂运算,则res[n+1][1]即为所得值,最后取一次mod即可。

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=10000007;
const int N=100;
long long n,m;
struct Mat
{
    ll mat[N][N];
};
Mat operator *(Mat a,Mat b)// 重载乘法
{
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i=1;i<=n+2;i++)
    {
        for(int j=1;j<=n+2;j++)
        {
            for(int k=1;k<=n+2;k++)
            {
                c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j])%mod;
            }
        }
    }
    return c;
}
Mat quickpow(Mat a,int m,int mod,Mat res)//快速矩阵幂运算
{
    while(m)
    {
        if(m&1)
            res=a*res;  //注意这里一定是左乘a
        a=a*a;
        m>>=1;
    }
    return res;
}


int main()
{
    Mat a,b;
    while(scanf("%lld%lld",&n,&m)!=EOF)
    {
        memset(a.mat,0,sizeof(a.mat));
        memset(b.mat,0,sizeof(b.mat));
        b.mat[1][1]=23;
        b.mat[n+2][1]=3;
        for(int i=2;i<=n+1;i++)
        {
            scanf("%lld",&b.mat[i][1]);
        }
        for(int i=1;i<=n+1;i++)
        {
            a.mat[i][1]=10;
            a.mat[i][n+2]=1;
        }
        a.mat[n+2][n+2]=1;
        for(int i=2;i<=n+1;i++)
        {
            for(int j=2;j<=i;j++)
            {
                a.mat[i][j]=1;
            }
        }
        Mat res;
        res=quickpow(a,m,mod,b);
        cout<<res.mat[n+1][1]%mod<<endl; //注意取mod是必须的
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43824158/article/details/87622484
233
今日推荐