Description
设$f(0)=0,f(1)=1,f(i)=f(i-1)+f(i-2)(i;geq;2)$,求$f(f(n));mod;10^9+7$。
Input
第一行一个数表示数据组数$t$。
接下来$t$行,每行包含一个正整数$n$。
Output
输出共$t$行,每行一个整数表示答案。
Sample Input
3
3
20
30
Sample Output
1
365706550
899899483
HINT
$1;leq;n;leq;10^100,0<t;leq;10^4$.
Solution
$f(x);equiv;f(x;mod;2; imes;10^9+16)(mod;10^9+7)$
$f(x);equiv;f(x;mod;329616)(mod;2; imes;10^9+16)$
所以只需要先将输入$mod;329616$求一次$f()$,然后$;mod;2; imes;10^9+16$求一次$f()$即可。
#include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define N 2 #define M1 329616ll #define M2 2000000016ll #define M3 1000000007ll using namespace std; typedef long long ll; struct matrix{ ll a[N][N];int n,m; }a,b,c; ll n;int t; inline ll read(){ ll ret=0ll;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)){ ret=((ret<<1ll)+(ret<<3ll)+c-'0')%M1; c=getchar(); } return ret; } inline matrix mul(matrix a,matrix b,ll p){ matrix ret; ret.n=a.n;ret.m=b.m; for(int i=0;i<ret.n;++i) for(int j=0;j<ret.m;++j){ ret.a[i][j]=0ll; for(int k=0;k<ret.n;++k) ret.a[i][j]=(ret.a[i][j]+a.a[i][k]*b.a[k][j]%p)%p; } return ret; } inline matrix po(matrix a,ll k,ll p){ matrix ret; ret.n=ret.m=a.n; for(int i=0;i<ret.n;++i) for(int j=0;j<ret.m;++j) if(i!=j) ret.a[i][j]=0ll; else ret.a[i][j]=1ll; while(k){ if(k&1ll) ret=mul(ret,a,p); a=mul(a,a,p);k>>=1ll; } return ret; } inline void Aireen(){ a.n=2;a.m=1;a.a[0][0]=1ll; b.n=b.m=2;b.a[0][0]=b.a[0][1]=b.a[1][0]=1ll; scanf("%d",&t); while(t--){ n=read(); if(n<=1){ printf("%lld ",n);continue; } c=mul(po(b,n-1ll,M2),a,M2); if(c.a[0][0]<=1){ printf("%lld ",c.a[0][0]);continue; } c=mul(po(b,c.a[0][0]-1ll,M3),a,M3); printf("%lld ",c.a[0][0]); } } int main(){ freopen("fibonacci.in","r",stdin); freopen("fibonacci.out","w",stdout); Aireen(); fclose(stdin); fclose(stdout); return 0; }