求(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
",(A[0][0]*2 + mod - 1) % mod);
}
int main()
{
    scanf("%lld",&n);
    solve();
    return 0 ;
}
View Code
原文地址:https://www.cnblogs.com/shuaihui520/p/9359298.html