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 a 0,1 = 233,a 0,2 = 2333,a 0,3 = 23333…) Besides, in 233 matrix, we got a i,j = a i-1,j +a i,j-1( i,j ≠ 0). Now you have known a 1,0,a 2,0,…,a n,0, could you tell me a n,m in the 233 matrix?
There are multiple test cases. Please process till EOF.
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).
For each case, output a n,m mod 10000007.
1 1
1
2 2
0 0
3 7
23 47 16
234
2799
72937
题意: 题目规定一个233矩阵,就是第一行依次是0,233,2333,23333…..
给你矩阵的第一列的n个数,让你求在矩阵中点(n,m)坐标的值 mod 1e7,范围: n≤10,m≤109
分析: 根据这个提示我们可以直观的构造模型,因为我们得构造233这个数列,我们只需要两个元素就可以构造即:23和3 F[n+1] = F[n]*10+3即可,我们还知道矩阵不超过10行,所以我们开一个13*13的矩阵即可
第一列 * [矩阵] = 第二列
初始值依次为 23 a(1,0) a(2,0) .... a(n,0) 3
具体见下图(以n = 4为例)
#include
#define ll long long
#define mod(x) ((x)%MOD)
using namespace std;
const int MOD = 1e7 + 7;
struct mat {
ll m[13][13];
}a,unit,ans;
int mm,n;
void init() {
memset(unit.m,0,sizeof(unit.m));
memset(a.m,0,sizeof(a.m));
for(int i = 1;i <= n;i++) {
cin>>unit.m[0][i];
unit.m[0][i] = mod(unit.m[0][i]);
}
unit.m[0][0] = 23;
unit.m[0][n+1] = 3;
for(int i = 0;i <= n;i++) {
a.m[0][i] = 10;
}
for(int i = 1;i <= n;i++)
for(int j = i;j <= n;j++)
a.m[i][j] = 1;
for(int i = 0;i <= n+1;i++) {
a.m[n+1][i] = 1;
}
}
mat operator *(mat m1,mat m2) {
mat t;
ll r;
for(int i = 0;i < n+2;i++) {
for(int j = 0;j < n+2;j++) {
r = 0;
for(int k = 0;k < n+2;k++) {
r = mod(r*1ll + mod(mod(m1.m[i][k]) * 1ll * mod(m2.m[k][j])));
}
t.m[i][j] = r;
}
}
return t;
}
mat quick_pow(ll x) {
mat t = unit;
while(x) {
if(x & 1) t = t*a;
a = a*a;
x >>= 1;
}
return t;
}
int main(){
ios_base::sync_with_stdio(0);
while(cin>>n>>mm) {
init();
if(mm == 0 && n == 0) {
cout<<0<continue;
}
ans = quick_pow(mm);
cout<0][n]<return 0;
}