1. 程式人生 > 其它 >【luogu1962】【矩陣乘法】【快速冪】斐波那契數列

【luogu1962】【矩陣乘法】【快速冪】斐波那契數列

技術標籤:洛谷矩陣乘法快速冪

傳送門

題目背景

大家都知道,斐波那契數列是滿足如下性質的一個數列:

F n = { 1 ( n ≤ 2 ) F n − 1 + F n − 2 ( n ≥ 3 ) F_n = \left\{\begin{aligned} 1 \space (n \le 2) \\ F_{n-1}+F_{n-2} \space (n\ge 3) \end{aligned}\right. Fn={1(n2)Fn1+Fn2(n3)

題目描述

請你求出 F n   m o d   1 0 9 + 7 F_n \bmod 10^9 + 7 Fnmod109+7

的值。

輸入格式

一行一個正整數 n n n

輸出格式

輸出一行一個整數表示答案。

輸入輸出樣例
輸入 #1
5
輸出 #1
5
輸入 #2
10
輸出 #2
55
說明/提示
【資料範圍】

對於 60 % 60\% 60% 的資料, 1 ≤ n ≤ 92 1\le n \le 92 1n92
對於 100 % 100\% 100% 的資料, 1 ≤ n < 2 63 1\le n < 2^{63} 1n<263


解題思路

詳情請見矩陣乘法

單純的我沒有意識到 n n n真的會 = 1 =1 =1: )


Code

#include <iostream>
#include <
cstring> #include <cstdio> using namespace std; const int Mod = 1000000007; long long n; struct DT{ int n, m; long long aed[5][5]; }A, B, Ac; DT operator *(DT a, DT b){ DT c; c.n = a.n, c.m = b.m; memset (c.aed, 0, sizeof (c.aed)); for (int k = 1; k <= a.m; k++) for (int i = 1; i <=
c.n; i++) for (int j = 1; j <= c.m; j++) c.aed[i][j] = (c.aed[i][j] + a.aed[i][k] * b.aed[k][j] % Mod) % Mod; return c; } void power (long long n){ if (n == 1) { Ac = A; return; } power (n / 2); Ac = Ac * Ac; if (n % 2) Ac = Ac * A; } int main(){ A.n = A.m = 2; A.aed[1][2] = A.aed[2][1] = A.aed[2][2] = 1; Ac = A; B.n = 1, B.m = 2; B.aed[1][1] = B.aed[1][2] = 1; scanf ("%lld", &n); if (n <= 2) printf ("1"); else { power (n - 1); B = B * Ac; printf ("%lld", B.aed[1][1]); } }