题意: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;
}