题意:有一个矩阵横排第一行初始是0,233,2333,23333...,然后给出计算公式a[i][j] = a[i - 1][j] + a[i][j - 1],然后给出了n和m和第一列的各值要求计算a[n][m]的值。
题解:n <= 10但m <= 10^9,空间和时间花费都大,已知第一列a0,a1,a2......an,那么第二列每个数字就是b1 = a1 + 233,b2 = b1 + a2 = a1 + a2 + 233... 找到特点后构造矩阵然后用矩阵快速幂求解。
#include <stdio.h>
#include <string.h>
#define ll long long
const int N = 15;
const int MOD = 10000007;
int n, m;
struct Mat {
ll a[N][N];
Mat() {
memset(a, 0, sizeof(a));
}
Mat operator * (Mat b) {
Mat c;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
c.a[i][j] = (c.a[i][j] + a[i][k] * b.a[k][j]) % MOD;
return c;
}
};
Mat f(Mat b, int m) {
Mat c;
for (int i = 0; i < n; i++)
c.a[i][i] = 1;
while (m) {
if (m & 1)
c = c * b;
b = b * b;
m >>= 1;
}
return c;
}
int main() {
while (scanf("%d%d", &n, &m) == 2) {
Mat A;
A.a[0][0] = 1;
A.a[1][0] = 1;
A.a[1][1] = 10;
n += 2;
for (int i = 2; i < n; i++)
for (int j = 1; j <= i; j++)
A.a[i][j] = 1;
A = f(A, m);
ll temp[N], res = 0;
temp[0] = 3;
temp[1] = 233;
for (int i = 2; i < n; i++)
scanf("%lld", &temp[i]);
for (int i = 0; i < n; i++)
res = (res + temp[i] * A.a[n - 1][i] % MOD) % MOD;
printf("%lld\n", res);
}
return 0;
}