剑指 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];
}
}