剑指 Offer 10- I. 斐波那契数列
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示:
0 <= n <= 100
思路:
矩阵快速幂
Acwing 1303. 斐波那契前 n 项和
大家都知道 Fibonacci 数列吧,f1=1,f2=1,f3=2,f4=3,…,fn=fn−1+fn−2
现在问题很简单,输入 n 和 m,求 fn 的前 n 项和 Snmodm。
输入格式
共一行,包含两个整数 n 和 m。
输出格式
输出前 n 项和 Snmodm 的值。
数据范围
1≤n≤2000000000
1≤m≤1000000010
输入样例:
5 1000
输出样例:
12
思路:
矩阵快速幂
/*Fn = [fn, f(n+1), sn]F(n+1) = [f(n+1), f(n+2), s(n+1)]F(n+1) = Fn * [[0, 1, 0][1, 1, 1][0, 0, 1]]*/import java.util.*;public class Main {static final int N = 3;static int n, mod;public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();mod = sc.nextInt();int[][] f1 = {{1, 1, 1}};int[][] b = {{0, 1, 0},{1, 1, 1},{0, 0, 1}};n--;while (n > 0) {if ((n & 1) == 1) {mul(f1, f1, b);}n >>= 1;mul(b, b, b);}System.out.println(f1[0][2]);}static void mul(int[][] c, int[][] a, int[][] b) {int x = a.length, y = a[0].length, z = b.length;int[][] res = new int[x][y];for (int i = 0; i < x; i++) {for (int j = 0; j < y; j++) {long sum = 0;for (int k = 0; k < z; k++)sum += 1L * a[i][k] * b[k][j];res[i][j] = (int)(sum % mod);}}for (int i = 0; i < x; i++)for (int j = 0; j < y; j++)c[i][j] = res[i][j];}}
AcWing 1217. 垒骰子
思路:
矩阵快速幂
import java.util.*;public class Main {static final int MOD = (int)(1e9 + 7);static int[] map = {3, 4, 5, 0, 1, 2};static int[][] cof = new int[6][6];static int[][] f = new int[6][6];static int n, m;public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();Arrays.fill(f[0], 4);for (int i = 0; i < 6; i++) {Arrays.fill(cof[i], 4);}while (m-- > 0) {int x = sc.nextInt(), y = sc.nextInt();x--;y--;cof[x][map[y]] = 0;cof[y][map[x]] = 0;}n--;while (n > 0) {if ((n & 1) == 1) {mul(f, f, cof);}n >>= 1;mul(cof, cof, cof);}long res = 0;for (int i = 0; i < 6; i++)res = (res + f[0][i]) % MOD;System.out.println(res);}static void mul(int[][] c, int[][] a, int[][] b) {int n = c.length, m = c[0].length, size = b.length;long[][] res = new long[n][m];for (int k = 0; k < size; k++) {for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {res[i][j] = (res[i][j] + 1L * a[i][k] * b[k][j]) % MOD;}}}for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)c[i][j] = (int)res[i][j];}}
