题目大意
F [ n ] = ( 5 + 1 2 ) n − 1 F[n] = (\frac{\sqrt{5}+1}{2})^{n-1} F[n]=(25+1)n−1
求 F ( x ) F(x) F(x) 的前 n n n 项和。
这题。。。考数学。
实则求斐波那契数列前n项和。
于是构建矩阵-像这样。
使得一个【f[n-2],f[n-1],S[n-2]】的矩阵乘上它变成【f[n-1],f[n],S[n]】。
以此递推。
- | f[n-1] | f[n] | S[n-1] |
---|---|---|---|
f[n-2] | 0 | 1 | 0 |
f[n-1] | 1 | 1 | 1 |
S[n-2] | 0 | 1 |
这个构建出来的矩阵求个快速幂,再乘上初始矩阵即可得到答案。
Code
#include<cstdio>
long long n;
struct asdf{
long long n,m;
long long k[5][5];
} A,B,C;
asdf operator *(asdf aa, asdf bb){
//矩阵乘法
asdf cc;
cc.n = aa.n;
cc.m = bb.m;
for(long long i = 1; i <= cc.n; ++i)
for(long long j = 1 ;j <= cc.m; ++j)
cc.k[i][j] = 0;
for(long long i = 1; i <= cc.n; ++i)
for(long long j = 1; j <= cc.m; ++j)
for(long long l = 1; l <= aa.m; ++l)
cc.k[i][j] = (cc.k[i][j] + aa.k[i][l] * bb.k[l][j] % 1000000007) % 1000000007;
return cc;
}
asdf ksm(long long l){
//快速幂
if(l == 1) return A;
asdf ll = ksm(l/2);
if(l % 2 == 0) return ll * ll;
return ll * ll * A;
}
int main(){
scanf("%lld",&n);
if(n == 1){
printf("1");
return 0;
}
A.n = 3; A.m = 3;
A.k[1][1] = A.k[1][3] = A.k[3][2] = A.k[1][3] = 0; //构建矩阵
A.k[2][1] = A.k[1][2] = A.k[2][2] = A.k[2][3] = A.k[3][3] = 1;
C.n = 1; C.m = 3;
C.k[1][1] = C.k[1][2] = 1; C.k[1][3] = 1; //初始矩阵
B = ksm(n-1);
B = C * B;
printf("%lld",B.k[1][3]); //输出和