HDU_3306
由于N很大,所以需要在找出递推关系的基础上用二分矩阵来优化计算过程。
根据S(n)=S(n-1)+A(n)^2,A(n)^2=X^2*A(n-1)^2+Y^2*A(n-2)^2+2*X*Y*A(n-1)*A(n-2),A(n)*A(n-1)=Y*A(n-1)*A(n-2)+X*A(n-1)^2,可以构造如下的矩阵,然后用二分矩阵的方法求解即可。
#include<stdio.h> #include<string.h> #define D 10007 #define MAXD 4 int N, X, Y; struct Matrix { int a[MAXD][MAXD]; Matrix() { memset(a, 0, sizeof(a)); } }; Matrix multiply(Matrix &x, Matrix &y) { int i, j, k, ans; Matrix z; for(k = 0; k < 4; k ++) for(i = 0; i < 4; i ++) if(x.a[i][k]) { for(j = 0; j < 4; j ++) if(y.a[k][j]) z.a[i][j] = (z.a[i][j] + x.a[i][k] * y.a[k][j]) % D; } return z; } void powmod(Matrix &unit, Matrix &mat, int n) { while(n) { if(n & 1) unit = multiply(mat, unit); n >>= 1; mat = multiply(mat, mat); } } void solve() { int i; Matrix unit, mat; for(i = 0; i < 4; i ++) unit.a[i][0] = 1; mat.a[0][0] = mat.a[0][1] = 1; mat.a[1][1] = (X * X) % D, mat.a[1][2] = (Y * Y) % D, mat.a[1][3] = (2 * X * Y) % D; mat.a[2][1] = 1; mat.a[3][1] = X, mat.a[3][3] = Y; powmod(unit, mat, N); printf("%d\n", unit.a[0][0]); } int main() { while(scanf("%d%d%d", &N, &X, &Y) == 3) { X %= D, Y %= D; solve(); } return 0; }