diff --git "a/solution/1400-1499/1411.Number of Ways to Paint N \303\227 3 Grid/README.md" "b/solution/1400-1499/1411.Number of Ways to Paint N \303\227 3 Grid/README.md" index bd42052c77dc8..7337d570944d0 100644 --- "a/solution/1400-1499/1411.Number of Ways to Paint N \303\227 3 Grid/README.md" +++ "b/solution/1400-1499/1411.Number of Ways to Paint N \303\227 3 Grid/README.md" @@ -64,10 +64,10 @@ 把每一行所有可能的状态进行分类。根据对称性原理,当一行只有 $3$ 个元素时,所有合法状态分类为:$010$ 型, $012$ 型。 -- 当状态为 $010$ 型时:下一行可能的状态为:$101$, $102$, $121$, $201$, $202$。这 $5$ 个状态可归纳为 $3$ 个 $010$ 型,$2$ 个 $012$ 型。 -- 当状态为 $012$ 型时:下一行可能的状态为:$101$, $120$, $121$, $201$。这 $4$ 个状态可归纳为 $2$ 个 $010$ 型,$2$ 个 $012$ 型。 +- 当状态为 $010$ 型时:下一行可能的状态为 $101$, $102$, $121$, $201$, $202$。这 $5$ 个状态可归纳为 $3$ 个 $010$ 型,以及 $2$ 个 $012$ 型。 +- 当状态为 $012$ 型时:下一行可能的状态为 $101$, $120$, $121$, $201$。这 $4$ 个状态可归纳为 $2$ 个 $010$ 型,以及 $2$ 个 $012$ 型。 -综上所述,可以得到:$newf0 = 3 \times f0 + 2 \times f1$, $newf1 = 2 \times f0 + 2 \times f1$。 +综上所述,可以得到 $newf0 = 3 \times f0 + 2 \times f1$, $newf1 = 2 \times f0 + 2 \times f1$。 时间复杂度 $O(n)$,其中 $n$ 是网格的行数。空间复杂度 $O(1)$。 @@ -85,7 +85,7 @@ $$ 最终的答案即为 $f[n][j]$ 的总和,其中 $j$ 是任意合法的状态。 -我们注意到,$f[i][j]$ 只和 $f[i - 1][k]$ 有关,因此我们可以使用滚动数组优化空间复杂度。 +我们注意到 $f[i][j]$ 只和 $f[i - 1][k]$ 有关,因此我们可以使用滚动数组优化空间复杂度。 时间复杂度 $O((m + n) \times 3^{2m})$,空间复杂度 $O(3^m)$。其中 $n$ 和 $m$ 分别是网格的行数和列数。 diff --git a/solution/2900-2999/2951.Find the Peaks/README.md b/solution/2900-2999/2951.Find the Peaks/README.md index fb30a52a45f68..0c7bde3aa2d0f 100644 --- a/solution/2900-2999/2951.Find the Peaks/README.md +++ b/solution/2900-2999/2951.Find the Peaks/README.md @@ -53,6 +53,14 @@ mountain[2] 也不可能是峰值,因为它不严格大于 mountain[3] 和 mou +**方法一:直接遍历** + +我们直接遍历下标 $i \in [1, n-2]$,对于每个下标 $i$,如果满足 $mountain[i-1] < mountain[i]$ 并且 $mountain[i + 1] < mountain[i]$,那么 $mountain[i]$ 就是一个峰值,我们将下标 $i$ 加入答案数组中。 + +遍历结束后,返回答案数组即可。 + +时间复杂度 $O(n)$,其中 $n$ 是数组的长度。忽略答案数组的空间消耗,空间复杂度 $O(1)$。 + ### **Python3** diff --git a/solution/2900-2999/2951.Find the Peaks/README_EN.md b/solution/2900-2999/2951.Find the Peaks/README_EN.md index 42e37604fa17c..120b9ec576c02 100644 --- a/solution/2900-2999/2951.Find the Peaks/README_EN.md +++ b/solution/2900-2999/2951.Find the Peaks/README_EN.md @@ -47,6 +47,14 @@ So the answer is [1,3]. ## Solutions +**Solution 1: Direct Traversal** + +We directly traverse the index $i \in [1, n-2]$. For each index $i$, if $mountain[i-1] < mountain[i]$ and $mountain[i + 1] < mountain[i]$, then $mountain[i]$ is a peak, and we add index $i$ to the answer array. + +After the traversal ends, we return the answer array. + +The time complexity is $O(n)$, where $n$ is the length of the array. Ignoring the space consumption of the answer array, the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/2900-2999/2952.Minimum Number of Coins to be Added/README.md b/solution/2900-2999/2952.Minimum Number of Coins to be Added/README.md index 5d622298cfb23..cc8090e23dde6 100644 --- a/solution/2900-2999/2952.Minimum Number of Coins to be Added/README.md +++ b/solution/2900-2999/2952.Minimum Number of Coins to be Added/README.md @@ -56,6 +56,19 @@ +**方法一:贪心 + 构造** + +我们不妨假设当前需要构造的金额为 $s$,且我们已经构造出了 $[0,...,s-1]$ 内的所有金额。如果此时有一个新的硬币 $x$,我们把它加入到数组中,可以构造出 $[x, s+x-1]$ 内的所有金额。 + +接下来,分类讨论: + +- 如果 $x \le s$,那么我们可以将上面两个区间合并,得到 $[0, s+x-1]$ 内的所有金额。 +- 如果 $x \gt s$,那么我们就需要添加一个面值为 $s$ 的硬币,这样可以构造出 $[0, 2s-1]$ 内的所有金额。然后我们再考虑 $x$ 和 $s$ 的大小关系,继续分析。 + +因此,我们将数组 $coins$ 按照升序排序,然后从小到大遍历数组中的硬币。对于每个硬币 $x$,我们进行上述分类讨论,直到 $s > target$ 为止。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组的长度。 + ### **Python3** diff --git a/solution/2900-2999/2952.Minimum Number of Coins to be Added/README_EN.md b/solution/2900-2999/2952.Minimum Number of Coins to be Added/README_EN.md index 8bc098e2a3a00..97cda50a350d8 100644 --- a/solution/2900-2999/2952.Minimum Number of Coins to be Added/README_EN.md +++ b/solution/2900-2999/2952.Minimum Number of Coins to be Added/README_EN.md @@ -51,6 +51,19 @@ It can be shown that all integers from 1 to 20 are obtainable from the resulting ## Solutions +**Solution 1: Greedy + Construction** + +Suppose the current amount we need to construct is $s$, and we have already constructed all amounts in $[0,...,s-1]$. If there is a new coin $x$, we add it to the array, which can construct all amounts in $[x, s+x-1]$. + +Next, we discuss in two cases: + +- If $x \le s$, then we can merge the two intervals above to get all amounts in $[0, s+x-1]$. +- If $x \gt s$, then we need to add a coin with a face value of $s$, so that we can construct all amounts in $[0, 2s-1]$. Then we consider the size relationship between $x$ and $s$ and continue to analyze. + +Therefore, we sort the array $coins$ in ascending order, and then traverse the coins in the array from small to large. For each coin $x$, we discuss in the above two cases until $s > target$. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the length of the array. + ### **Python3** diff --git a/solution/2900-2999/2954.Count the Number of Infection Sequences/README.md b/solution/2900-2999/2954.Count the Number of Infection Sequences/README.md index 8791cc35a9137..db2c69aa878c6 100644 --- a/solution/2900-2999/2954.Count the Number of Infection Sequences/README.md +++ b/solution/2900-2999/2954.Count the Number of Infection Sequences/README.md @@ -67,7 +67,26 @@ ```python - +mod = 10**9 + 7 +mx = 10**5 +fac = [1] * (mx + 1) +for i in range(2, mx + 1): + fac[i] = fac[i - 1] * i % mod + + +class Solution: + def numberOfSequence(self, n: int, sick: List[int]) -> int: + nums = [b - a - 1 for a, b in pairwise([-1] + sick + [n])] + ans = 1 + s = sum(nums) + ans = fac[s] + for x in nums: + if x: + ans = ans * pow(fac[x], mod - 2, mod) % mod + for x in nums[1:-1]: + if x > 1: + ans = ans * pow(2, x - 1, mod) % mod + return ans ``` ### **Java** @@ -75,19 +94,217 @@ ```java - +class Solution { + private static final int MOD = (int) (1e9 + 7); + private static final int MX = 100000; + private static final int[] FAC = new int[MX + 1]; + + static { + FAC[0] = 1; + for (int i = 1; i <= MX; i++) { + FAC[i] = (int) ((long) FAC[i - 1] * i % MOD); + } + } + + public int numberOfSequence(int n, int[] sick) { + int m = sick.length; + int[] nums = new int[m + 1]; + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (int i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + int s = 0; + for (int x : nums) { + s += x; + } + int ans = FAC[s]; + for (int x : nums) { + if (x > 0) { + ans = (int) ((long) ans * qpow(FAC[x], MOD - 2) % MOD); + } + } + for (int i = 1; i < nums.length - 1; ++i) { + if (nums[i] > 1) { + ans = (int) ((long) ans * qpow(2, nums[i] - 1) % MOD); + } + } + return ans; + } + + private int qpow(long a, long n) { + long ans = 1; + for (; n > 0; n >>= 1) { + if ((n & 1) == 1) { + ans = ans * a % MOD; + } + a = a * a % MOD; + } + return (int) ans; + } +} ``` ### **C++** ```cpp - +const int MX = 1e5; +const int MOD = 1e9 + 7; +int fac[MX + 1]; + +auto init = [] { + fac[0] = 1; + for (int i = 1; i <= MX; ++i) { + fac[i] = 1LL * fac[i - 1] * i % MOD; + } + return 0; +}(); + +int qpow(long long a, long long n) { + long long ans = 1; + for (; n > 0; n >>= 1) { + if (n & 1) { + ans = (ans * a) % MOD; + } + a = (a * a) % MOD; + } + return ans; +} + +class Solution { +public: + int numberOfSequence(int n, vector& sick) { + int m = sick.size(); + vector nums(m + 1); + + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (int i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + + int s = accumulate(nums.begin(), nums.end(), 0); + long long ans = fac[s]; + for (int x : nums) { + if (x > 0) { + ans = ans * qpow(fac[x], MOD - 2) % MOD; + } + } + for (int i = 1; i < nums.size() - 1; ++i) { + if (nums[i] > 1) { + ans = ans * qpow(2, nums[i] - 1) % MOD; + } + } + return ans; + } +}; ``` ### **Go** ```go +const MX = 1e5 +const MOD = 1e9 + 7 + +var fac [MX + 1]int + +func init() { + fac[0] = 1 + for i := 1; i <= MX; i++ { + fac[i] = fac[i-1] * i % MOD + } +} + +func qpow(a, n int) int { + ans := 1 + for n > 0 { + if n&1 == 1 { + ans = (ans * a) % MOD + } + a = (a * a) % MOD + n >>= 1 + } + return ans +} + +func numberOfSequence(n int, sick []int) int { + m := len(sick) + nums := make([]int, m+1) + + nums[0] = sick[0] + nums[m] = n - sick[m-1] - 1 + for i := 1; i < m; i++ { + nums[i] = sick[i] - sick[i-1] - 1 + } + + s := 0 + for _, x := range nums { + s += x + } + ans := fac[s] + for _, x := range nums { + if x > 0 { + ans = ans * qpow(fac[x], MOD-2) % MOD + } + } + for i := 1; i < len(nums)-1; i++ { + if nums[i] > 1 { + ans = ans * qpow(2, nums[i]-1) % MOD + } + } + return ans +} +``` +### **TypeScript** + +```ts +const MX = 1e5; +const MOD: bigint = BigInt(1e9 + 7); +const fac: bigint[] = Array(MX + 1); + +const init = (() => { + fac[0] = 1n; + for (let i = 1; i <= MX; ++i) { + fac[i] = (fac[i - 1] * BigInt(i)) % MOD; + } + return 0; +})(); + +function qpow(a: bigint, n: number): bigint { + let ans = 1n; + for (; n > 0; n >>= 1) { + if (n & 1) { + ans = (ans * a) % MOD; + } + a = (a * a) % MOD; + } + return ans; +} + +function numberOfSequence(n: number, sick: number[]): number { + const m = sick.length; + const nums: number[] = Array(m + 1); + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (let i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + + const s = nums.reduce((acc, x) => acc + x, 0); + let ans = fac[s]; + for (let x of nums) { + if (x > 0) { + ans = (ans * qpow(fac[x], Number(MOD) - 2)) % MOD; + } + } + for (let i = 1; i < nums.length - 1; ++i) { + if (nums[i] > 1) { + ans = (ans * qpow(2n, nums[i] - 1)) % MOD; + } + } + return Number(ans); +} ``` ### **...** diff --git a/solution/2900-2999/2954.Count the Number of Infection Sequences/README_EN.md b/solution/2900-2999/2954.Count the Number of Infection Sequences/README_EN.md index 25f3383162979..9e4f155800b75 100644 --- a/solution/2900-2999/2954.Count the Number of Infection Sequences/README_EN.md +++ b/solution/2900-2999/2954.Count the Number of Infection Sequences/README_EN.md @@ -59,25 +59,242 @@ Finally, the child at position 2 gets infected because it is adjacent to childre ### **Python3** ```python +mod = 10**9 + 7 +mx = 10**5 +fac = [1] * (mx + 1) +for i in range(2, mx + 1): + fac[i] = fac[i - 1] * i % mod + +class Solution: + def numberOfSequence(self, n: int, sick: List[int]) -> int: + nums = [b - a - 1 for a, b in pairwise([-1] + sick + [n])] + ans = 1 + s = sum(nums) + ans = fac[s] + for x in nums: + if x: + ans = ans * pow(fac[x], mod - 2, mod) % mod + for x in nums[1:-1]: + if x > 1: + ans = ans * pow(2, x - 1, mod) % mod + return ans ``` ### **Java** ```java +class Solution { + private static final int MOD = (int) (1e9 + 7); + private static final int MX = 100000; + private static final int[] FAC = new int[MX + 1]; + + static { + FAC[0] = 1; + for (int i = 1; i <= MX; i++) { + FAC[i] = (int) ((long) FAC[i - 1] * i % MOD); + } + } + + public int numberOfSequence(int n, int[] sick) { + int m = sick.length; + int[] nums = new int[m + 1]; + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (int i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + int s = 0; + for (int x : nums) { + s += x; + } + int ans = FAC[s]; + for (int x : nums) { + if (x > 0) { + ans = (int) ((long) ans * qpow(FAC[x], MOD - 2) % MOD); + } + } + for (int i = 1; i < nums.length - 1; ++i) { + if (nums[i] > 1) { + ans = (int) ((long) ans * qpow(2, nums[i] - 1) % MOD); + } + } + return ans; + } + private int qpow(long a, long n) { + long ans = 1; + for (; n > 0; n >>= 1) { + if ((n & 1) == 1) { + ans = ans * a % MOD; + } + a = a * a % MOD; + } + return (int) ans; + } +} ``` ### **C++** ```cpp +const int MX = 1e5; +const int MOD = 1e9 + 7; +int fac[MX + 1]; + +auto init = [] { + fac[0] = 1; + for (int i = 1; i <= MX; ++i) { + fac[i] = 1LL * fac[i - 1] * i % MOD; + } + return 0; +}(); + +int qpow(long long a, long long n) { + long long ans = 1; + for (; n > 0; n >>= 1) { + if (n & 1) { + ans = (ans * a) % MOD; + } + a = (a * a) % MOD; + } + return ans; +} +class Solution { +public: + int numberOfSequence(int n, vector& sick) { + int m = sick.size(); + vector nums(m + 1); + + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (int i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + + int s = accumulate(nums.begin(), nums.end(), 0); + long long ans = fac[s]; + for (int x : nums) { + if (x > 0) { + ans = ans * qpow(fac[x], MOD - 2) % MOD; + } + } + for (int i = 1; i < nums.size() - 1; ++i) { + if (nums[i] > 1) { + ans = ans * qpow(2, nums[i] - 1) % MOD; + } + } + return ans; + } +}; ``` ### **Go** ```go +const MX = 1e5 +const MOD = 1e9 + 7 + +var fac [MX + 1]int + +func init() { + fac[0] = 1 + for i := 1; i <= MX; i++ { + fac[i] = fac[i-1] * i % MOD + } +} + +func qpow(a, n int) int { + ans := 1 + for n > 0 { + if n&1 == 1 { + ans = (ans * a) % MOD + } + a = (a * a) % MOD + n >>= 1 + } + return ans +} + +func numberOfSequence(n int, sick []int) int { + m := len(sick) + nums := make([]int, m+1) + + nums[0] = sick[0] + nums[m] = n - sick[m-1] - 1 + for i := 1; i < m; i++ { + nums[i] = sick[i] - sick[i-1] - 1 + } + + s := 0 + for _, x := range nums { + s += x + } + ans := fac[s] + for _, x := range nums { + if x > 0 { + ans = ans * qpow(fac[x], MOD-2) % MOD + } + } + for i := 1; i < len(nums)-1; i++ { + if nums[i] > 1 { + ans = ans * qpow(2, nums[i]-1) % MOD + } + } + return ans +} +``` + +### **TypeScript** + +```ts +const MX = 1e5; +const MOD: bigint = BigInt(1e9 + 7); +const fac: bigint[] = Array(MX + 1); + +const init = (() => { + fac[0] = 1n; + for (let i = 1; i <= MX; ++i) { + fac[i] = (fac[i - 1] * BigInt(i)) % MOD; + } + return 0; +})(); + +function qpow(a: bigint, n: number): bigint { + let ans = 1n; + for (; n > 0; n >>= 1) { + if (n & 1) { + ans = (ans * a) % MOD; + } + a = (a * a) % MOD; + } + return ans; +} + +function numberOfSequence(n: number, sick: number[]): number { + const m = sick.length; + const nums: number[] = Array(m + 1); + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (let i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + const s = nums.reduce((acc, x) => acc + x, 0); + let ans = fac[s]; + for (let x of nums) { + if (x > 0) { + ans = (ans * qpow(fac[x], Number(MOD) - 2)) % MOD; + } + } + for (let i = 1; i < nums.length - 1; ++i) { + if (nums[i] > 1) { + ans = (ans * qpow(2n, nums[i] - 1)) % MOD; + } + } + return Number(ans); +} ``` ### **...** diff --git a/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.cpp b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.cpp new file mode 100644 index 0000000000000..eb31593022080 --- /dev/null +++ b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.cpp @@ -0,0 +1,50 @@ +const int MX = 1e5; +const int MOD = 1e9 + 7; +int fac[MX + 1]; + +auto init = [] { + fac[0] = 1; + for (int i = 1; i <= MX; ++i) { + fac[i] = 1LL * fac[i - 1] * i % MOD; + } + return 0; +}(); + +int qpow(long long a, long long n) { + long long ans = 1; + for (; n > 0; n >>= 1) { + if (n & 1) { + ans = (ans * a) % MOD; + } + a = (a * a) % MOD; + } + return ans; +} + +class Solution { +public: + int numberOfSequence(int n, vector& sick) { + int m = sick.size(); + vector nums(m + 1); + + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (int i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + + int s = accumulate(nums.begin(), nums.end(), 0); + long long ans = fac[s]; + for (int x : nums) { + if (x > 0) { + ans = ans * qpow(fac[x], MOD - 2) % MOD; + } + } + for (int i = 1; i < nums.size() - 1; ++i) { + if (nums[i] > 1) { + ans = ans * qpow(2, nums[i] - 1) % MOD; + } + } + return ans; + } +}; diff --git a/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.go b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.go new file mode 100644 index 0000000000000..502c31fcae283 --- /dev/null +++ b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.go @@ -0,0 +1,51 @@ +const MX = 1e5 +const MOD = 1e9 + 7 + +var fac [MX + 1]int + +func init() { + fac[0] = 1 + for i := 1; i <= MX; i++ { + fac[i] = fac[i-1] * i % MOD + } +} + +func qpow(a, n int) int { + ans := 1 + for n > 0 { + if n&1 == 1 { + ans = (ans * a) % MOD + } + a = (a * a) % MOD + n >>= 1 + } + return ans +} + +func numberOfSequence(n int, sick []int) int { + m := len(sick) + nums := make([]int, m+1) + + nums[0] = sick[0] + nums[m] = n - sick[m-1] - 1 + for i := 1; i < m; i++ { + nums[i] = sick[i] - sick[i-1] - 1 + } + + s := 0 + for _, x := range nums { + s += x + } + ans := fac[s] + for _, x := range nums { + if x > 0 { + ans = ans * qpow(fac[x], MOD-2) % MOD + } + } + for i := 1; i < len(nums)-1; i++ { + if nums[i] > 1 { + ans = ans * qpow(2, nums[i]-1) % MOD + } + } + return ans +} \ No newline at end of file diff --git a/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.java b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.java new file mode 100644 index 0000000000000..7ccab4d2517d0 --- /dev/null +++ b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.java @@ -0,0 +1,49 @@ +class Solution { + private static final int MOD = (int) (1e9 + 7); + private static final int MX = 100000; + private static final int[] FAC = new int[MX + 1]; + + static { + FAC[0] = 1; + for (int i = 1; i <= MX; i++) { + FAC[i] = (int) ((long) FAC[i - 1] * i % MOD); + } + } + + public int numberOfSequence(int n, int[] sick) { + int m = sick.length; + int[] nums = new int[m + 1]; + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (int i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + int s = 0; + for (int x : nums) { + s += x; + } + int ans = FAC[s]; + for (int x : nums) { + if (x > 0) { + ans = (int) ((long) ans * qpow(FAC[x], MOD - 2) % MOD); + } + } + for (int i = 1; i < nums.length - 1; ++i) { + if (nums[i] > 1) { + ans = (int) ((long) ans * qpow(2, nums[i] - 1) % MOD); + } + } + return ans; + } + + private int qpow(long a, long n) { + long ans = 1; + for (; n > 0; n >>= 1) { + if ((n & 1) == 1) { + ans = ans * a % MOD; + } + a = a * a % MOD; + } + return (int) ans; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.py b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.py new file mode 100644 index 0000000000000..561b7b8e49e23 --- /dev/null +++ b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.py @@ -0,0 +1,20 @@ +mod = 10**9 + 7 +mx = 10**5 +fac = [1] * (mx + 1) +for i in range(2, mx + 1): + fac[i] = fac[i - 1] * i % mod + + +class Solution: + def numberOfSequence(self, n: int, sick: List[int]) -> int: + nums = [b - a - 1 for a, b in pairwise([-1] + sick + [n])] + ans = 1 + s = sum(nums) + ans = fac[s] + for x in nums: + if x: + ans = ans * pow(fac[x], mod - 2, mod) % mod + for x in nums[1:-1]: + if x > 1: + ans = ans * pow(2, x - 1, mod) % mod + return ans diff --git a/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.ts b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.ts new file mode 100644 index 0000000000000..9a9033621afb2 --- /dev/null +++ b/solution/2900-2999/2954.Count the Number of Infection Sequences/Solution.ts @@ -0,0 +1,46 @@ +const MX = 1e5; +const MOD: bigint = BigInt(1e9 + 7); +const fac: bigint[] = Array(MX + 1); + +const init = (() => { + fac[0] = 1n; + for (let i = 1; i <= MX; ++i) { + fac[i] = (fac[i - 1] * BigInt(i)) % MOD; + } + return 0; +})(); + +function qpow(a: bigint, n: number): bigint { + let ans = 1n; + for (; n > 0; n >>= 1) { + if (n & 1) { + ans = (ans * a) % MOD; + } + a = (a * a) % MOD; + } + return ans; +} + +function numberOfSequence(n: number, sick: number[]): number { + const m = sick.length; + const nums: number[] = Array(m + 1); + nums[0] = sick[0]; + nums[m] = n - sick[m - 1] - 1; + for (let i = 1; i < m; i++) { + nums[i] = sick[i] - sick[i - 1] - 1; + } + + const s = nums.reduce((acc, x) => acc + x, 0); + let ans = fac[s]; + for (let x of nums) { + if (x > 0) { + ans = (ans * qpow(fac[x], Number(MOD) - 2)) % MOD; + } + } + for (let i = 1; i < nums.length - 1; ++i) { + if (nums[i] > 1) { + ans = (ans * qpow(2n, nums[i] - 1)) % MOD; + } + } + return Number(ans); +}