[bsoj1855] Fibonacci数列


题目描述

  Fibonacci数列是大家再熟悉不过的东东了.
  由于吃完饭后没有什么事做,ChengYu决定计算Fibonacci数列的第n项来帮助消化,现在他希望你也做同样的事. ^_^ Fibonacci数列增长非常快,为了节约宝贵的纸张,所以只要计算答案除以1729的余数即可.


输入格式

多组数据,每行一个正整数n(n<=3456789012).


输出格式

对于每个输入,输出结果.


样例数据

样例输入

1
2
3

样例输出

1
1
2


题目分析

弱智题目,矩阵加速递推,也可以找循环节,略过。


源代码

找循环节

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
long long f[5005],n;
int Fibonacci(int n) {
    f[1]=0;f[2]=1;
    for(int i=2;i<=n;i++) {
        f[0]=f[1];
        f[1]=f[2];
        f[2]=(f[1]+f[0])%1729;
    }
    return f[2]%1729;
}
int main() {
    while(cin>>n) {
        n%=1008;
        if(n==0)cout<<Fibonacci(1008)<<endl;
        else cout<<Fibonacci(n)<<endl;
    }
    return 0;
}

矩阵快速幂

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
    int num=0,bj=1;
    char x=getchar();
    while(x<'0'||x>'9') {
        if(x=='-')bj=-1;
        x=getchar();
    }
    while(x>='0'&&x<='9') {
        num=num*10+x-'0';
        x=getchar();
    }
    return num*bj;
}
typedef long long LL;
const int maxn=5,mod=1729;
struct Matrix {
    LL n,m,a[maxn][maxn];
    Matrix(LL n,LL m) {
        this->n=n;
        this->m=m;
        memset(a,0,sizeof(a));
    }
    Matrix(LL n,LL m,char E) { //单位矩阵
        this->n=n;
        this->m=m;
        memset(a,0,sizeof(a));
        for(int i=1; i<=n; i++)a[i][i]=1;
    }
    void init(LL n,LL m) {
        this->n=n;
        this->m=m;
        memset(a,0,sizeof(a));
    }
    LL* operator [] (const LL x) {
        return a[x];
    }
    Matrix operator = (Matrix b) {
        init(b.n,b.m);
        for(int i=1; i<=b.n; i++)
            for(int j=1; j<=b.m; j++)
                a[i][j]=b[i][j];
    }
    Matrix operator + (Matrix& b) {
        for(int i=1; i<=b.n; i++)
            for(int j=1; j<=b.m; j++)
                a[i][j]+=b[i][j];
    }
    void operator += (Matrix& b) {
        *this=*this+b;
    }
    Matrix operator - (Matrix& b) {
        for(int i=1; i<=b.n; i++)
            for(int j=1; j<=b.m; j++)
                a[i][j]-=b[i][j];
    }
    void operator -= (Matrix& b) {
        *this=*this-b;
    }
    Matrix operator * (LL k) {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                a[i][j]*=k;
    }
    void operator *= (LL k) {
        *this=*this*k;
    }
    Matrix operator * (Matrix& b) {
        Matrix c(n,b.m);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=b.m; j++)
                for(int k=1; k<=m; k++)
                    c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mod;
        return c;
    }
    void operator *= (Matrix& b) {
        *this=*this*b;
    }
    Matrix operator ^ (LL b) {
        Matrix ans(n,m,'e'),a=*this;
        while(b>0) {
            if(b&1)ans=ans*a;
            a*=a;
            b>>=1;
        }
        return ans;
    }
    void Output() {
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++)
                printf("%lld ",a[i][j]);
            putchar('\n');
        }
    }
};
LL n;
int main() {
    Matrix a(1,2),b(2,2);
    a[1][1]=a[1][2]=1;
    b[1][1]=b[1][2]=b[2][1]=1;
    while(scanf("%lld",&n)!=EOF) {
        Matrix tmp=b^(n-2);
        printf("%lld\n",(a*tmp)[1][1]);
    } 
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值