1365 Fib(N) mod Fib(K) [斐波那契相关]
Fib(N)表示斐波那契数列的第N项(),给出N和K,求 。由于结果太大,输出 的结果。
首先要知道
,
在 意义下继续化简
再要知道
首先要知道 的相关内容如下.
:
再看斐波那契数列的转移矩阵如下,
矩阵相等, 行列式也相等,
.
所以在 意义下, .
再看原式:
设 , ,
则
其中 可能为负数, 这里又要引入
.
然后就可以 辣
总结一下, 该题涉及的知识点有
#include<bits/stdc++.h>
#define reg register
typedef long long ll;
const int mod = 1e9 + 7;
ll N;
ll K;
struct Matrix{ int C[4][4]; Matrix(){ memset(C, 0, sizeof C); } };
Matrix modify(const Matrix &a, const Matrix &b){
Matrix s;
for(reg int i = 1; i <= 2; i ++)
for(reg int j = 1; j <= 2; j ++)
for(reg int k = 1; k <= 2; k ++){
int &t = s.C[i][j];
t = (1ll*t + (1ll*a.C[i][k]*b.C[k][j]%mod)) % mod;
}
return s;
}
Matrix ma_Ksm(Matrix a, ll b){
Matrix s;
for(reg int i = 1; i <= 2; i ++) s.C[i][i] = 1;
while(b){
if(b & 1) s = modify(s, a);
a = modify(a, a); b >>= 1;
}
return s;
}
ll get(ll k){
Matrix res, I;
res.C[1][1] = 1;
I.C[1][1] = I.C[1][2] = I.C[2][1] = 1;
I = ma_Ksm(I, k);
res = modify(res, I);
return res.C[1][2];
}
void Work(){
scanf("%lld%lld", &N, &K);
ll x = N/K, y = N%K;
if(x & 1){
x = (x+1)/2, y = K-y-1;
x = (K & 1) * x;
ll Ans = ((x+y&1)?-1:1) * get(y + 1);
if(Ans < 0) Ans = (Ans + get(K) + mod) % mod;
printf("%lld\n", Ans);
}else{
x >>= 1;
if(!(K&1)) x = 0;
ll Ans = ((x&1)?-1:1) * get(y);
if(Ans < 0) Ans = (Ans + get(K) + mod) % mod;
printf("%lld\n", Ans);
}
}
int main(){
freopen("fib.in", "r", stdin);
freopen("fib.out", "w", stdout);
int T; scanf("%d", &T);
while(T --) Work();
return 0;
}