题意:矩阵的第一行是233,2333,23333……,第一列输入,矩阵每个位置满足ai,j = ai-1,j +ai,j-1( i,j ≠ 0),求矩阵的最左下角的元素
思路:矩阵快速幂
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const ll mod=10000007;
const int maxn=20;
struct Matrix{
int n,m;
ll a[maxn][maxn];
void clear(){
n=m=0;
memset(a,0,sizeof(a));
}
Matrix operator + (const Matrix &b) const{
Matrix tmp;
tmp.n=n;
tmp.m=m;
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
tmp.a[i][j]=a[i][j]+b.a[i][j];
tmp.a[i][j]%=mod;
}
}
return tmp;
}
Matrix operator - (const Matrix &b) const{
Matrix tmp;
tmp.n=n;
tmp.m=m;
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
tmp.a[i][j]=a[i][j]-b.a[i][j];
}
}
return tmp;
}
Matrix operator * (const Matrix &b) const{
Matrix tmp;
tmp.clear();
tmp.n=n;
tmp.m=b.m;
for(int i=0;i<n;++i)
{
for(int j=0;j<b.m;++j)
{
for(int k=0;k<m;++k){tmp.a[i][j]+=a[i][k]*b.a[k][j];tmp.a[i][j]%=mod;}
}
}
return tmp;
}
};
Matrix fast_pow(Matrix a,int n)
{
Matrix ret;
ret.clear();
ret.n=a.n;
ret.m=a.m;
for(int i=0;i<ret.n;++i)
{
ret.a[i][i]=1;
}
while(n)
{
if(n&1)
{
ret=ret*a;
}
a=a*a;
n>>=1;
}
return ret;
}
int main()
{
// freopen("data.txt","r",stdin);
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
m++;
n++;
Matrix ans;
ans.n=n+1;
ans.m=1;
for(int i=1;i<n;++i)
{
scanf("%I64d",&ans.a[i][0]);
}
ans.a[0][0]=233;
ans.a[n][0]=3;
Matrix mul;
mul.clear();
mul.n=n+1;
mul.m=n+1;
mul.a[0][0]=10;
mul.a[0][n]=1;
for(int i=1;i<mul.n-1;++i)
{
for(int j=0;j<=i;++j)mul.a[i][j]=1;
}
mul.a[n][n]=1;
mul=fast_pow(mul,m-1);
ans=mul*ans;
printf("%I64d\n",ans.a[n-1][0]);
}
return 0;
}