又见斐波那契

题目描述 

这是一个加强版的斐波那契数列。
给定递推式
求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;
}
posted @ 2020-07-22 14:52  HighLights  阅读(186)  评论(0)    收藏  举报