求(3+开根5) N次方的整数部分最后3位
求(3+开根5) N次方的整数部分最后3位,请补足前导零 。
分析:首先(1)=(3+开根5) N次方的展开为 an + bn * 根号5 的形式 。 同时也有 (2)=(3-开根5) N次方 = an - bn * 根号5 ;
则可以得出 (1)+(2) = 2*an,, so (1) = 2*an - (2) , 同时可以知道0<(2)<1 ; so (1)的整数部分为2*an - 1 ;
所以只要我们可以求出 an 那答案就。。嘻嘻。。
(3 + g5) n+1次方 = (3+g5) (3+g5)n次方 = (3+g5)(an+bn * g5);
得到递推式 :
an+1 = 3*an + 5*bn;
bn+1 = an+3*bn;
a0 = 1,b0 = 0;
我们用矩阵表示递推式,就可以用快速幂了,因为只要最后3为,so mod 1000;
在C中 printf(“%03d) 可以自动补0.
#include<stdio.h> #include<vector> using namespace std; #define inf 0x3f3f3f3f typedef vector<int>vec; typedef vector<vec>mat; typedef long long ll; const int M = 10000; const int mod = 1000 ; ll n; mat mul(mat &A , mat &B) { mat C(A.size() , vec(B.size())); for(int i=0 ; i<A.size() ; i++) { for(int k=0 ; k<B.size() ; k++) { if(A[i][k]==0) continue; for(int j=0 ; j<B[0].size() ; j++) { if(B[k][j]==0) continue; C[i][j] = (C[i][j]+A[i][k]*B[k][j])%M; } } } return C; } mat pow(mat A,ll n) { mat B(A.size(),vec(A.size())); for(int i=0 ; i<A.size() ; i++) B[i][i]=1; while(n>0) { if(n&1) B = mul(B,A); A = mul(A,A); n >>= 1; } return B; } void solve() { mat A(2,vec(2,0)); A[0][0] = 3 ; A[0][1] = 5; A[1][0] = 1 ; A[1][1] = 3; A = pow(A,n); printf("%03d\n",(A[0][0]*2 + mod - 1) % mod); } int main() { scanf("%lld",&n); solve(); return 0 ; }