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
#include
#include
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<