题意:f(0) = 1, f(1) = 1, f(n) = x*f(n - 1) + y*f(n - 2),要计算输出Sn = f(0)^2 + f(1)^2 + … + f(n)^2。
题解:构造矩阵
其中 f(n)*f(n) = x^2*f(n-1)^2 + y^2*f(n-2)^2 + 2xy*f(n-1)*f(n-2)。
#include <stdio.h>
#include <string.h>
const int MOD = 10007;
struct Mat {
long long g[6][6];
}ori, res;
long long n, x, y;
Mat multiply(Mat x, Mat y) {
Mat temp;
memset(temp.g, 0, sizeof(temp.g));
for (int i = 0; i < 6; i++)
for (int j = 0; j < 6; j++)
for (int k = 0; k < 6; k++)
temp.g[i][j] = (temp.g[i][j] + x.g[i][k] * y.g[k][j]) % MOD;
return temp;
}
void calc(long long n) {
while (n) {
if (n & 1)
ori = multiply(ori, res);
n >>= 1;
res = multiply(res, res);
}
}
int main() {
while (scanf("%lld%lld%lld", &n, &x, &y) == 3) {
memset(ori.g, 0, sizeof(ori.g));
memset(res.g, 0, sizeof(res.g));
ori.g[0][0] = ori.g[0][1] = ori.g[0][2] = ori.g[0][3] = ori.g[0][4] = 1;
ori.g[0][5] = 2;
res.g[0][0] = res.g[2][4] = x % MOD;
res.g[1][0] = res.g[4][4] = y % MOD;
res.g[2][2] = res.g[2][5] = (x * x) % MOD;
res.g[3][2] = res.g[3][5] = (y * y) % MOD;
res.g[4][2] = res.g[4][5] = (2 * x * y) % MOD;
res.g[0][1] = res.g[2][3] = res.g[5][5] = 1;
calc(n - 1);
printf("%lld\n", ori.g[0][5]);
}
return 0;
}