如果用递归方式的话时很慢的,需要压栈,不停的调用很费时间,完全不建议。

代码:

#include <cstdio>
#include<iostream>
using namespace std;
int f(long long n) {
    if(n <= 1)return n;
    return (f(n - 1) + f(n - 2)) % 10000;
}
int main() {
    long long n;
    cin>>n;
    cout<<f(n);
}

也可以用循环,会快些,O(n)的时间,效率还是太低。

代码:

#include <cstdio>
#include<iostream>
using namespace std;
int f(long long n) {
    if(n <= 1)return n;
    int a = 0,b = 1,c;
    long long i = 2;
    while(i <= n) {
        c = (a + b) % 10000;
        a = b;
        b = c;
        i ++;
    }
    return c;
}
int main() {
    long long n;
    cin>>n;
    cout<<f(n);
}

斐波那契数列有通项公式,Fn = 1/根5 * (((1 + 根5) / 2)^n - ((1 - 根5) / 2)^n),但是有无理数,无法简单的求得取模后的结果。其实不用求出通项。

可以用矩阵解决。

Fn = Fn-1 + Fn-2,

Fn+1 = Fn + Fn-1,

(Fn+1 Fn)T = A(Fn Fn-1)T,

A = 

(Fn+1 Fn)T = A^n(F1 F0)T,

只需要求出矩阵A的n次方之后,把结果矩阵再跟(1 0)T相乘就得出答案。

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

void mul(int (*a)[2],int (*b)[2]) {
    int d[2][2] = {0};
    for(int i = 0;i < 2;i ++) {
        for(int j = 0;j < 2;j ++) {
            for(int k = 0;k < 2;k ++) {
                d[i][j] += (a[i][k] * b[k][j]) % 10000;
            }
            d[i][j] %= 10000;
        }
    }
    for(int i = 0;i < 2;i ++) {
        for(int j = 0;j < 2;j ++) {
            a[i][j] = d[i][j];
        }
    }
}
int f(long long n) {
    int a[2][2] = {1,1,1,0},d[2][2] = {1,0,0,1};
    while(n) {
        if(n % 2)mul(d,a);
        n /= 2;
        mul(a,a);
    }
    return d[1][0];
}
int main() {
    long long n;
    cin>>n;
    cout<<f(n);
}