233 Matrix
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
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).
1 1 1 2 2 0 0 3 7 23 47 16
234 2799 72937Hint![]()
题目大意:
对于一个n+1行,m+1列的矩阵A[n+1][m+1],已知a[0][1]=233,a[0][2]=2333,a[0][3]=23333,…………并且对于矩阵当中元素的值,有a[i][j]=a[i-1][j]+a[i][j-1](i,j!=0)。给出a[1][0],a[2][0],…………,a[n-1][0],a[n][0]以及n,m,求解a[n][m](矩阵第n行第m列元素的值)。
解题思路:
因为a[0][1]=233,a[0][2]=2333,a[0][3]=23333,…………,所以有a[0][i]=10*a[0][i-1]+3(i>1,a[0][1]=233)
如果令a[0][0]=23,那么a[0][i]=10*a[0][i-1]+3(i>0,a[0][0]=23)
则对于n+1行,m+1列的矩阵A,有
第一列(下标j=0)
第二列(下标j=1)
第三列(下标j=2)
对上述矩阵的各列适当变形得:
第一列(下标j=0)
第二列(下标j=1)
第三列(下标j=2)
所以有
根据上面的递推公式,我们可以构造矩阵得,
(其中)
矩阵快速幂
代码如下:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-6)
#define inf (1<<28)
#define sqr(x) (x) * (x)
#define mod 10000007
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
#define MAX 25
int n;
struct Matrix
{
ll a[MAX][MAX];
Matrix()
{
memset(a,0,sizeof(a));
}
};
Matrix operator *(Matrix a,Matrix b)
{
Matrix c;
ll i,j,k;
memset(c.a,0,sizeof(c.a));
for(k=0;k<n+2;k++)
{
for(i=0;i<n+2;i++)
{
if(a.a[i][k]==0)
continue;
for(j=0;j<n+2;j++)
{
if(b.a[k][j]==0)
continue;
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
c.a[i][j]%=mod;
}
}
}
return c;
}
Matrix operator ^(Matrix a,int k)
{
Matrix c;
ll i;
for(i=0;i<n+2;i++)
c.a[i][i]=1;
while(k)
{
if(k&1)
c=c*a;
a=a*a;
k>>=1;
}
return c;
}
int main()
{
Matrix a,b,c;
ll i,j,k,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
a.a[0][0]=23;
for(i=1;i<=n;i++)
{
scanf("%d",&a.a[i][0]);
}
a.a[n+1][0]=3;
for(i=0;i<n+2;i++)
{
for(j=0;j<n+2;j++)
{
b.a[i][j]=0;
if(j==0&&i!=(n+1))
b.a[i][j]=10;
if(j==(n+1))
b.a[i][j]=1;
if(j==0&&i==(n+1))
b.a[i][j]=0;
if(i>=1&&i<=n&&j>=1&&j<=n)
{
if(i>=j)
b.a[i][j]=1;
}
}
}
b=b^m;
long long ans=0;
for(i=0;i<n+2;i++)
ans=(ans+b.a[n][i]*a.a[i][0])%mod;
printf("%I64d\n",ans%mod);
}
return 0;
}