题意:给定n和k,求斐波那契数列里能被k整除的第n个数的下标。
解:有两个结论:
1. 当首次能被k整除的数为第i个数时时,数列中能被i整除,当且仅当其下标为i的倍数。
2. 斐波那契数列中模k的循环节长度不超过6k。
于是就很简单了,在小于6k的数里找出第一个能被k整除的数,然后乘n。
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define maxx 600005 #define inf 0x3f3f3f3f #define mod 1000000007 signed main(){ int T; scanf("%d",&T); while(T--){ ll n,k; scanf("%lld%lld",&n,&k); if(k==1){ printf("%lld\n",n%mod); continue; } ll a=1,b=1; ll res; for(int i=3;i<=k*6;i++){ ll c=(a+b)%k; if(!c){ res=i; break; } a=b%k;b=c%k; } printf("%lld\n",((res%mod)*(n%mod))%mod); } return 0; }
*证明
1.
假设第一个能被k整除的数为fib[i],fib[i]=m*k,fib[i+1]=m*k+fib[i-1],fib[i+2]=2*m*k+fib[i-1],...,fib[i+i]=i*m*k+fib[i]*fib[i-1],由于fib[i]和fib[i-1]互质(辗转相除法可得),故fib[2*i]为大于fib[i]的第一个能被k整除的数。
2.
可见皮萨诺周期
—— For my dearest Lappland.