5119: Fibonacci_I
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 44 Solved: 17
[Submit][Status][Web Board]
Description
小P是一个数学爱好者,这天他打算研究一下斐波那契数列。他想知道第ii个斐波那契数ai是多少。
斐波那契数列是这样的:1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 …
比如,第3个数字是2,第5个数字是5,以此类推。
但有一个问题,当i很大的时候,ai也会变得非常大,小P认为那么大就没有必要了,于是他想了一个办法来减少这个数字的大小。
小P的方法是,把每个数字加上5,并除以13求其余数。换句话来说,对于原来的斐波那契数列ai,经小P处理之后bi=(ai+5) mod 13,其中mod是取余数。
Input
第一行是一个T,代表着有T组数据。
每一个数据仅包含一个数n,代表着小P想求的bi数列中第n个数字,也就是bn。
1≤T≤100
1≤n≤109
Output
对于每一组数据,输出其答案bn。
Sample Input
3
1
3
7
Sample Output
6
7
5
CODE
矩阵快速幂,暴力求解 去学习矩阵快速幂
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include <fstream>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#include<set>
//#include<unordered_map>
//#include<unordered_set>
#define ll long long
using namespace std;
const int INF=0x3f3f3f3f;
const double pi=acos(-1.0),eps=1e-8;
/*
inline ll read()
{
ll x=0;char ch=getchar();
while(ch>'9'||ch<'0')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}*/
const int mod=13;
const int N=2;
ll tmp[N][N],res[N][N];
void multi(ll a[][N],ll b[][N],int n)
{
memset(tmp,0,sizeof(tmp));
for(ll i=0; i<n; i++)
{
for(ll j=0; j<n; j++)
{
for(ll k=0; k<n; k++)
{
tmp[i][j]+=(a[i][k]*b[k][j])%mod;
}
tmp[i][j]=tmp[i][j]%mod;
}
}
for(ll i=0; i<n; i++)
for(ll j=0; j<n; j++)
a[i][j]=tmp[i][j];
}
void Pow(ll a[][N],ll m,int n)
{
memset(res,0,sizeof(res));//m是幂,n是矩阵大小
for(ll i=0; i<n; i++)
res[i][i]=1;
while(m)
{
if(m&1)
multi(res,a,n);//res=res*a;复制直接在multi里面实现了;
multi(a,a,n);//a=a*a
m>>=1;
}
}
ll a[N][N];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ll m;
int n;
scanf("%lld",&m);
n=2;
a[0][0]=1,a[0][1]=1,a[1][0]=1,a[1][1]=0;
Pow(a,m,n);
printf("%lld\n",(res[1][0]+5)%13);
}
return 0;
}