• poj3070 Fibonacci


    Fibonacci
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 11510   Accepted: 8179

    Description

    In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

    An alternative formula for the Fibonacci sequence is

    .

    Given an integer n, your goal is to compute the last 4 digits of Fn.

    Input

    The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.

    Output

    For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).

    Sample Input

    0
    9
    999999999
    1000000000
    -1

    Sample Output

    0
    34
    626
    

    6875

    这题可以用矩阵快速幂,算是入门题。

    方法一:直接计算.

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define inf 0x7fffffff
    #define pi acos(-1.0)
    #define MOD 10000
    ll fast_mod(ll n)
    {
        ll i,j,k;
        ll ans[2][2]={1,0,0,1}; //初始化为单位矩阵,也是最终的答案
        ll temp[2][2];  //做为矩阵乘法中的中间变量
        ll a[2][2]={1,1,1,0};
        while(n)
        {
            if(n&1){        //实现 ans*=t,其中要先把ans赋值给tmp然后用ans=tmp*t
                for(i=0;i<2;i++){
                    for(j=0;j<2;j++){
                        temp[i][j]=ans[i][j];
                    }
                }
                ans[0][0]=ans[0][1]=ans[1][0]=ans[1][1]=0;
                for(i=0;i<2;i++){
                    for(j=0;j<2;j++){
                        for(k=0;k<2;k++){
                            ans[i][j]=(ans[i][j]+(temp[i][k]*a[k][j]+MOD)%MOD+MOD  )%MOD;
                        }
                    }
                }
            }
            for(i=0;i<2;i++){
                for(j=0;j<2;j++){
                    temp[i][j]=a[i][j];
                }
    
            }
            a[0][0]=a[0][1]=a[1][0]=a[1][1]=0;
            for(i=0;i<2;i++){
                for(j=0;j<2;j++){
                    for(k=0;k<2;k++){
                        a[i][j]=(a[i][j]+(temp[i][k]*temp[k][j]+MOD)%MOD+MOD )%MOD; //这里先加MOD然后再取模是为了模完后不为负数
                    }
                }
            }
            n>>=1;
        }
        return (ans[0][1]+MOD)%MOD;
    }
    
    
    int main()
    {
        ll n,m,i,j;
        while(scanf("%lld",&n)!=EOF && n!=-1){
            printf("%lld
    ",fast_mod(n));
        }
        return 0;
    }                                                                                                                                                                                                                                                                                                                                                                                                           方法二:考虑1×2的矩阵【f[n-2],f[n-1]】。我们可以通过乘以一个2×2的矩阵A,得到矩阵:【f[n-1],f[n]】。
    
    
    即:【f[n-2],f[n-1]】*A = 【f[n-1],f[n]】=【f[n-1],f[n-1]+f[n-2]】
    
    
    可以构造出这个2×2矩阵A,即:
    0 1 
    1 1
    所以,有【f[1],f[2]】×A=【f[2],f[3]】
    又因为矩阵乘法满足结合律,故有:
    【f[1],f[2]】×A ^(n-1) =【f[n],f[n+1]】                                                                                                                                                                                                                                <pre name="code" class="cpp">#include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define inf 0x7fffffff
    #define pi acos(-1.0)
    #define MOD 10000
    ll ans[2][2];
    void fast_mod(ll n)
    {
        ll i,j,k;
        ll temp[2][2];  //做为矩阵乘法中的中间变量
        ll a[2][2]={0,1,1,1};
        while(n)
        {
            if(n&1){        //实现 ans*=t,其中要先把ans赋值给tmp然后用ans=tmp*t
                for(i=0;i<2;i++){
                    for(j=0;j<2;j++){
                        temp[i][j]=ans[i][j];
                    }
                }
                ans[0][0]=ans[0][1]=ans[1][0]=ans[1][1]=0;
                for(i=0;i<2;i++){
                    for(j=0;j<2;j++){
                        for(k=0;k<2;k++){
                            ans[i][j]=(ans[i][j]+(temp[i][k]*a[k][j]+MOD)%MOD+MOD  )%MOD;
                        }
                    }
                }
            }
            for(i=0;i<2;i++){
                for(j=0;j<2;j++){
                    temp[i][j]=a[i][j];
                }
    
            }
            a[0][0]=a[0][1]=a[1][0]=a[1][1]=0;
            for(i=0;i<2;i++){
                for(j=0;j<2;j++){
                    for(k=0;k<2;k++){
                        a[i][j]=(a[i][j]+(temp[i][k]*temp[k][j]+MOD)%MOD+MOD )%MOD; //这里先加MOD然后再取模是为了模完后不为负数
                    }
                }
            }
            n>>=1;
        }
    }
    
    
    int main()
    {
        ll n,m,i,j;
        while(scanf("%lld",&n)!=EOF && n!=-1){
            if(n==0){
                printf("0
    ");continue;
            }
            if(n==1){
                printf("1
    ");continue;
            }
            if(n==2){
                printf("1
    ");continue;
            }
            ans[0][0]=1;
            ans[0][1]=0;
            ans[1][0]=0;
            ans[1][1]=1;
            fast_mod(n-1);
            printf("%lld
    ",ans[1][1]%MOD   );
        }
        return 0;
    }
    
    

    快速幂模板:
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define inf 0x7fffffff
    #define pi acos(-1.0)
    #define MOD 10000
    struct matrix{
        ll n,m,i;
        ll data[99][99];
        void init_danwei(){
            for(i=0;i<n;i++){
                data[i][i]=1;
            }
        }
    }a,b,c,d,t;
    
    matrix multi(matrix &a,matrix &b){
        ll i,j,k;
        matrix temp;
        temp.n=a.n;
        temp.m=b.m;
        for(i=0;i<temp.n;i++){
            for(j=0;j<temp.m;j++){
                temp.data[i][j]=0;
            }
        }
        for(i=0;i<a.n;i++){
            for(k=0;k<a.m;k++){
                if(a.data[i][k]>0){
                    for(j=0;j<b.m;j++){
                        temp.data[i][j]=(temp.data[i][j]+(a.data[i][k]*b.data[k][j])%MOD )%MOD;
                    }
                }
            }
        }
        return temp;
    }
    
    matrix fast_mod(matrix a,ll n){
        matrix ans;
        ans.n=a.n;
        ans.m=a.m;
        memset(ans.data,0,sizeof(ans.data));
        ans.init_danwei();
        while(n>0){
            if(n&1)ans=multi(ans,a);
            a=multi(a,a);
            n>>=1;
        }
        return ans;
    }
    
    int main()
    {
        ll n,m,i,j;
        while(scanf("%lld",&n)!=EOF && n!=-1)
        {
            a.data[0][0]=a.data[0][1]=a.data[1][0]=1;
            a.data[1][1]=0;
            a.n=a.m=2;
            matrix ant=fast_mod(a,n);
            printf("%lld
    ",ant.data[0][1]%MOD);
        }
        return 0;
    }
    
    

    
                
    
  • 相关阅读:
    单例模式
    json 格式
    axios 获取不到数据错误
    sprint test 添加事务回滚机制
    springboot An incompatible version [1.1.32] of the APR based Apache Tomcat Native library is installed, while Tomcat requires version [1.2.14]
    spring boot 启动之后404
    废了
    tomcat 部署项目到服务器
    Druid 介绍及配置
    jq 全选
  • 原文地址:https://www.cnblogs.com/herumw/p/9464608.html
Copyright © 2020-2023  润新知