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

HDU - 5015 233 矩阵快速幂(构造矩阵)

 

 

 

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;  
}  



 

相关文章: