1. 程式人生 > 實用技巧 >又見斐波那契

又見斐波那契

題目描述

這是一個加強版的斐波那契數列。
給定遞推式 求F(n)的值,由於這個值可能太大,請對109+7取模。

輸入描述:

第一行是一個整數T(1 ≤ T ≤ 1000),表示樣例的個數。
以後每個樣例一行,是一個整數n(1 ≤ n ≤ 1018)。

輸出描述:

每個樣例輸出一行,一個整數,表示F(n) mod 1000000007。

輸入

4
1
2
3
100

輸出

1
16
57
558616258
/*  F(i) = F(i - 1) + F(i - 2) + i^3 + i^2 + i + 1
F(i)             1 1 1 1 1 1    F(i - 1)
F(i - 1)         1 0 0 0 0 0    F(i - 2)
(i + 1)^3        0 0 1 3 3 1      i ^ 3
(i + 1)^2        0 0 0 1 2 1      i ^ 2
i + 1            0 0 0 0 1 1      i
1                0 0 0 0 0 1      1
*/ #include<bits/stdc++.h> using namespace std; typedef long long LL; const LL MOD = 1e9 + 7; void mul(LL f[6][6], LL a[6][6], LL mod) { LL c[6][6]; memset(c, 0, sizeof(c)); for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { for (int k = 0; k < 6; k++) { c[i][j]
= (c[i][j] + f[i][k] * a[k][j]) % mod; } } } memcpy(f, c, sizeof(c)); } void mulself(LL a[6][6], LL mod) { LL c[6][6]; memset(c, 0, sizeof(c)); for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { for (int k = 0; k < 6; k++) { c[i][j]
= (c[i][j] + a[i][k] * a[k][j]) % mod; } } } memcpy(a, c, sizeof(c)); } int main() { LL n, T; cin >> T; while (T--) { cin >> n; n -= 1; LL a[6][6] = {{1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0}, {0, 0, 1, 3, 3, 1}, {0, 0, 0, 1, 2, 1}, {0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 1}}; LL f[6] = {1, 0, 8, 4, 2, 1}, ans[6][6] = {0}; for (int i = 0; i < 6; i++) ans[i][i] = 1; while (n) { if (n & 1) mul(ans, a, MOD); mulself(a, MOD); n >>= 1; } cout << (ans[0][0] * 1 + ans[0][1] * 0 + ans[0][2] * 8 + ans[0][3] * 4 + ans[0][4] * 2 + ans[0][5] * 1) % MOD << endl; } return 0; }