矩阵快速幂 - 湘潭大学
链接:https://www.nowcoder.com/acm/contest/105/G
来源:牛客网
题目描述
这是一个加强版的斐波那契数列。
给定递推式
求F(n)的值,由于这个值可能太大,请对109+7取模。
输入描述:
第一行是一个整数T(1 ≤ T ≤ 1000),表示样例的个数。18
以后每个样例一行,是一个整数n(1 ≤ n ≤ 10
)。
输出描述:
每个样例输出一行,一个整数,表示F(n) mod 1000000007。
示例1
输入
4 1 2 3 100
输出
1 16 57 558616258
题意 : 一个比较裸的题,只要构造出来矩阵就很容易。
![](https://images2018.cnblogs.com/blog/1213807/201804/1213807-20180430155542062-1282063885.png)
代码示例 :
#define ll long long const ll maxn = 1e6+5; const ll mod = 1000000007; const double eps = 1e-9; const double pi = acos(-1.0); const ll inf = 0x3f3f3f3f; ll n; struct mat { ll a[10][10]; }; const ll modulu[10][10] = { {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} }; mat mul(mat a, mat b){ mat r; memset(r.a, 0, sizeof(r.a)); for(ll i = 0; i < 6; i++){ for(ll j = 0; j < 6; j++){ for(ll k = 0; k < 6; k++){ r.a[i][j] += (a.a[i][k]*b.a[k][j])%mod; r.a[i][j] %= mod; } } } return r; } mat qpow(mat a, ll x){ mat b; memset(b.a, 0, sizeof(b.a)); for(ll i = 0; i <6; i++) b.a[i][i] = 1; while(x){ if (x&1) b = mul(b, a); a = mul(a, a); x >>= 1; } return b; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); ll t; cin >> t; while(t--){ scanf("%lld", &n); mat a; memcpy(a.a, modulu, sizeof(modulu)); if (n == 1) {printf("1\n"); continue;} else if (n == 0) {printf("0\n"); continue;} //for(ll i = 0; i < 6; i++){ //for(ll j = 0; j < 6; j++){ //prllf("%d ", a.a[i][j]); //} //prllf("\n"); //} a = qpow(a, n-1); ll sum = a.a[0][0]+a.a[0][2]*8+a.a[0][3]*4+a.a[0][4]*2+a.a[0][5]; printf("%lld\n", sum%mod); } return 0; }
东北日出西边雨 道是无情却有情