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.youkuaiyun.com/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;
}