1. 程式人生 > >求(3+開根5) N次方的整數部分最後3位

求(3+開根5) N次方的整數部分最後3位

\n using include none scan alt tdi typedef fine

求(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 ; }
View Code

求(3+開根5) N次方的整數部分最後3位