233 Matrix
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 4010 Accepted Submission(s): 2271
Problem Description
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 a0,1 = 233,a0,2 = 2333,a0,3 = 23333...) Besides, in 233 matrix, we got ai,j = ai-1,j +ai,j-1( i,j ≠ 0). Now you have known a1,0,a2,0,...,an,0, could you tell me an,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 ≤ 109). The second line contains n integers, a1,0,a2,0,...,an,0(0 ≤ ai,0 < 231).
Output
For each case, output an,m mod 10000007.
Sample Input
1 1 1 2 2 0 0 3 7 23 47 16
Sample Output
234 2799 72937
Hint
Source
2014 ACM/ICPC Asia Regional Xi'an Online
Recommend
hujie | We have carefully selected several similar problems for you: 6470 6469 6468 6467 6466
题意:
给你一个233矩阵,横纵坐标都是从0开始,第一行为0 233 2333 23333…… 依次往下延续,知道递推式子: A[i][j] = A[i-1][j] + A[i][j-1],给出第0列的n个数a[1~n](除了A【0】【0】),要求A[n][m]。
分析:
首先,我们设A[0][0]=23,这样一来,第一行就都满足 A[0][i]=(A[0][i-1])*10+3 的关系。
为了能由第0列推到第1列,我们在n+1列设为3
这样第0列的矩阵就为
23
a[1]
a[2]
a[3]
a[4]
3
由第0列转移到第1列则为
23*10+3
a[1]+23*10+3
a[2]+a[1]+23*10+3
a[3]+a[2]+a[1]+23*10+3
a[4]+a[3]+a[2]+a[1]+23*10+3
非常显然转移矩阵A就出来了:
10 0 0 0 0 1
10 1 0 0 0 1
10 1 1 0 0 1
10 1 1 1 0 1
10 1 1 1 1 1
0 0 0 0 0 1
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<vector>
#define N 10005
using namespace std;
const int MAXN= 100;
const int p= 10000007;
typedef long long ll;
ll len;
struct Matrix
{
long long M[MAXN][MAXN];
Matrix(const bool I = 0) ///初始化对角矩阵
{
memset(M, 0, sizeof(M));
if (I)
for(int i = 0; i < len; i++)
M[i][i] = 1;
}
Matrix operator *(const Matrix &y) ///矩阵乘法,对乘法重新定义
{
Matrix z;
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
for (int k = 0; k < len; k++)
z.M[i][j] = (z.M[i][j]+M[i][k]*y.M[k][j]%p)%p;
return z;
}
void out()
{
for (int i = 0; i <len; i++)
{
for (int j = 0; j < len; j++)
cout << M[i][j] << " ";
cout << "\n";
}
}
};
Matrix pow(Matrix A, long long b)///矩阵的快速幂
{
Matrix ans = Matrix(1);
for (; b; b>>=1)
{
if (b&1) ans = ans*A;
A = A*A;
}
return ans;
}
ll a[15];
int main()
{
int T;
ll n,m,k;
while(scanf("%lld%lld",&n,&m)!=-1)
{
len=n+2; ///构造矩阵的长度
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
a[0]=23;
a[n+1]=3;
Matrix ans;
for(int i=0;i<=n+1;i++)
{
ans.M[i][n+1]=1;
if(i==n+1) continue;
ans.M[i][0]=10;
for(int j=1;j<=i;j++)
ans.M[i][j]=1;
}
ll ans1=0;
ans=pow(ans,m);
//ans.out();
for(int i=0;i<len;i++)
ans1=(ans1+a[i]*ans.M[n][i])%p;
printf("%lld\n",ans1%p);
}
return 0;
}