快速求斐波那契

Description

Fibonacci数列,大家应该都很熟悉了吧? _

Fibonacci数列是这样定义的:

F[0]=0;

F[1]=1;

F[n]=F[n-1]+F[n-2], for n>1
大家都知道Fibonacci数列的增长速度是惊人的。当n=47时,F[47]=2971215073(>2^31)。由于数列的值增长太快,对于n,你只需要输出F[n]%12。
Input

第一行,一个整数T(1紧接着有T行,每一行有一个整数n(0<=n<=200000000)

Output

对于每一组测试数据n,输出一个整数m=F[n]%12。

Sample Input
4
0
1
2
47

Sample Output
0
1
1
1

简单暴力AC递推代码:

#include<iostream>
using namespace std;
 
int main(){
    int n,f0=0,f1=1,f=0;
    cin>>n;
    for (int i=1;i<=n;i++)
	{
        int a;
        cin>>a;
        if (a==0) cout<<0<<endl;
        else if (a==1) cout<<1<<endl;
        else
        {
        	f0=0,f1=1,f=0;
        	for (int j=2;j<=a;j++)
			{
            	f=(f0%12+f1%12)%12;
            	f0=f1;
            	f1=f;
        	}
        	cout<<f<<endl;
        }
    }
    return 0;
}

优化后的AC递推代码

#include <stdio.h>
using namespace std;
 
int main(){
    int n,f0=0,f1=1;
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
	{
        long long a;
        scanf("%lld",&a);
        if (a==0) printf("0\n");
        else if (a==1) printf("1\n");
        else
        {
        	f0=0,f1=1;
        	for (long long j=2;j<a;j+=2)
			{
            	f0=(f0%12+f1%12)%12;
            	f1=(f0%12+f1%12)%12;
        	}
        	if (a%2==0)
			{
				f0=(f0%12+f1%12)%12;
				f1=f0;
			} 
        	printf("%d\n",f1);
        }
    }
    return 0;
}

但还是只拿80分,如下样例通不过:
3
199999959
199981533
199993666

最后找了矩阵快速幂方法,链接为:
https://blog.csdn.net/NYIST_TC_LYQ/article/details/52981353
AC代码如下:

#include <iostream>
#include <cstddef>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int mod=12;
typedef vector<ll> vec;
typedef vector<vec> mat;
mat mul(mat &a,mat &b)//不太懂 
{
    mat c(a.size(),vec(b[0].size()));
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<2; j++)
        {
            for(int k=0; k<2; k++)
            {
                c[i][j]+=a[i][k]*b[k][j];
                c[i][j]%=mod;
            }
        }
    }
    return c;
}
mat pow(mat a,ll n)
{
    mat res(a.size(),vec(a.size()));
    for(int i=0; i<a.size(); i++)
        res[i][i]=1;//单位矩阵;
    while(n)
    {
        if(n&1) res=mul(res,a);
        a=mul(a,a);
        n/=2;
    }
    return res;
}
ll solve(ll n)
{
    mat a(2,vec(2));
    a[0][0]=1;
    a[0][1]=1;
    a[1][0]=1;
    a[1][1]=0;
    a=pow(a,n);
    return a[0][1];//也可以是a[1][0];
}
int main()
{
    ll n,x;
    cin>>n; 
    for (int i=1;i<=n;i++)
    {
        cin>>x;
		cout<<solve(x)<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43126361/article/details/83652047
今日推荐