题意:给出矩阵的第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]。
解法:看到n<=10和m<=10^9 应该对矩阵有些想法,现在我们假设要求A[a][b],则A[a][b] = A[a][b-1] + A[a-1][b] = A[a][b-1] + A[a-1][b-1] + A[a-2][b] = ...
这样相当于右图:,红色部分为绿色部分之和,而顶上的绿色部分很好求,左边的绿色部分(最多10个)其实就是:A[1][m-1],A[2][m-1]..A[n][m-1],即对每个1<=i<=n, A[i][m]都可由A[1][m-1],A[2][m-1]..A[n][m-1],于是建立12*12的矩阵:
,将中间矩阵求m-1次幂,与右边[A[0][1],A[1][1]..A[n][1],3]^T相乘,结果就可以得出了。
题解是转的别人的:http://www.cnblogs.com/whatbeg/p/3971994.html
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e7 + 7;
struct Matrix
{
int mat[15][15];
int n;
void init(int nn)
{
n = nn;
memset(mat, 0, sizeof(mat));
}
Matrix operator*(const Matrix &b) const
{
Matrix ret; ret.init(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
ret.mat[i][j] = 0;
for (int k = 0; k < n; k++)
{
ret.mat[i][j] += (long long)mat[i][k] * b.mat[k][j] % MOD;
if (ret.mat[i][j] >= MOD)
ret.mat[i][j] -= MOD;
}
}
return ret;
}
Matrix operator^(long long nn)
{
Matrix tmp = *this, ret; ret.init(this->n);
for (int i = 0; i < this->n; i++)
ret.mat[i][i] = 1;
while (nn)
{
if (nn & 1)ret = ret * tmp;
tmp = tmp * tmp;
nn >>= 1;
}
return *this = ret;
}
void print()
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
cout << mat[i][j] << (j == n - 1 ? "\n" : " ");
}
}
};
int inp[20], n, m;
Matrix A;
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
while (cin >> n >> m)
{
for (int i = 0; i < n; i++)
{
cin >> inp[i];
inp[i] %= MOD;
}
A.init(n + 2);
for (int j = 0; j < n; A.mat[n][j] = 1, j++)
for (int i = 0; i <= j; i++)
A.mat[i][j] = 1;
A.mat[n][n] = 10; A.mat[n + 1][n] = 3; A.mat[n + 1][n + 1] = 1;
//A.print();
A^m;
//A.print();
long long ans = 0;
for (int i = 0; i < n; i++)
{
ans += (long long)inp[i] * A.mat[i][n - 1] % MOD;
ans % MOD;
}
ans += (long long)233 * A.mat[n][n - 1];
ans %= MOD;
ans += (long long)A.mat[n + 1][n - 1];
ans %= MOD;
cout << ans << endl;
}
return 0;
}