题目大意:给出矩阵的第0行(233,2333,23333,…)和第0列a1,a2,… an(n<=10,m<=10^9),给出式子: A[i][j] = A[i-1][j] + A[i][j-1],求A[n][m]。
题目分析:这道题的矩阵十分的恶心巧妙,需要用打表的方式推。最后推出来的矩阵是:
10 0 0 0 ... 0 1
10 1 0 0 ... 0 1
10 1 1 0 ... 0 1
......
10 1 1 1 ... 1 1
0 0 0 0 ... 0 1
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int Mod=10000007;
const int N=13;
int n,m;
struct Node{
long long a[N][N];
void init(){
memset(a,0,sizeof(a));
for (int i=1;i<=n+2;i++) a[i][i]=1;
}
void del(){
memset(a,0,sizeof(a));
}
};
Node multi(Node a,Node b){
Node ans;
ans.del();
for (int i=1;i<=n+2;i++)
for (int k=1;k<=n+2;k++){
if (a.a[i][k]==0) continue;
for (int j=1;j<=n+2;j++)
ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%Mod;
}
return ans;
}
Node Pow(Node a,int p){
Node ans;
ans.init();
while (p){
if (p&1) ans=multi(ans,a);
a=multi(a,a);
p>>=1;
}
return ans;
}
int main(){
while (~scanf ("%d%d",&n,&m)){
Node tmp;
tmp.del();
tmp.a[1][1]=23;
for (int i=1;i<=n;i++)
scanf ("%d",&tmp.a[i+1][1]);
tmp.a[n+2][1]=3;
Node ans;
ans.del();
for (int i=1;i<=n+1;i++){ans.a[i][1]=10;ans.a[i][n+2]=1;}
ans.a[n+2][n+2]=1;
for (int i=2;i<=n+1;i++)
for (int j=2;j<=i;j++)
ans.a[i][j]=1;
ans=Pow(ans,m);
tmp=multi(ans,tmp);
printf ("%d\n",tmp.a[n+1][1]);
}
return 0;
}