zoukankan      html  css  js  c++  java
  • 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;
    }
    
    

    
                
    
  • 相关阅读:
    MFC Windows 程序设计>WinMain 简单Windows程序 命令行编译
    AT3949 [AGC022D] Shopping 题解
    CF643D Bearish Fanpages 题解
    CF643C Levels and Regions 题解
    CF241E Flights 题解
    CF671C Ultimate Weirdness of an Array 题解
    CF1592F Alice and Recoloring 题解
    GYM 102452E 题解
    CF494C Helping People 题解
    P5556 圣剑护符
  • 原文地址:https://www.cnblogs.com/herumw/p/9464608.html
Copyright © 2011-2022 走看看