Welcome to Subscribe On Youtube
3700. Number of ZigZag Arrays II
Description
You are given three integers n, l, and r.
A ZigZag array of length n is defined as follows:
- Each element lies in the range
[l, r]. - No two adjacent elements are equal.
- No three consecutive elements form a strictly increasing or strictly decreasing sequence.
Return the total number of valid ZigZag arrays.
Since the answer may be large, return it modulo 109 + 7.
A sequence is said to be strictly increasing if each element is strictly greater than its previous one (if exists).
A sequence is said to be strictly decreasing if each element is strictly smaller than its previous one (if exists).
Example 1:
Input: n = 3, l = 4, r = 5
Output: 2
Explanation:
There are only 2 valid ZigZag arrays of length n = 3 using values in the range [4, 5]:
[4, 5, 4][5, 4, 5]
Example 2:
Input: n = 3, l = 1, r = 3
Output: 10
Explanation:
There are 10 valid ZigZag arrays of length n = 3 using values in the range [1, 3]:
[1, 2, 1],[1, 3, 1],[1, 3, 2][2, 1, 2],[2, 1, 3],[2, 3, 1],[2, 3, 2][3, 1, 2],[3, 1, 3],[3, 2, 3]
All arrays meet the ZigZag conditions.
Constraints:
3 <= n <= 1091 <= l < r <= 75
Solutions
Solution 1
-
class Solution { private static final long MOD = 1_000_000_007L; public int zigZagArrays(int n, int l, int r) { int m = r - l + 1; int size = 2 * m; long[][] trans = new long[size][size]; for (int x = 0; x < m; x++) { for (int y = 0; y < x; y++) { trans[y][m + x] = 1; } } // down[x] -> up[y] where y > x for (int x = 0; x < m; x++) { for (int y = x + 1; y < m; y++) { trans[m + y][x] = 1; } } long[][] power = matrixPow(trans, n - 1); long[] init = new long[size]; for (int i = 0; i < m; i++) { init[i] = 1; init[m + i] = 1; } long[] result = multiply(power, init); long ans = 0; for (long v : result) { ans = (ans + v) % MOD; } return (int) ans; } private long[] multiply(long[][] mat, long[] vec) { int n = mat.length; long[] res = new long[n]; for (int i = 0; i < n; i++) { long sum = 0; for (int j = 0; j < n; j++) { sum = (sum + mat[i][j] * vec[j]) % MOD; } res[i] = sum; } return res; } private long[][] matrixPow(long[][] mat, long exp) { int n = mat.length; long[][] res = new long[n][n]; for (int i = 0; i < n; i++) { res[i][i] = 1; } while (exp > 0) { if ((exp & 1) == 1) { res = multiply(res, mat); } mat = multiply(mat, mat); exp >>= 1; } return res; } private long[][] multiply(long[][] a, long[][] b) { int n = a.length; long[][] res = new long[n][n]; for (int i = 0; i < n; i++) { for (int k = 0; k < n; k++) { if (a[i][k] == 0) continue; long aik = a[i][k]; for (int j = 0; j < n; j++) { if (b[k][j] == 0) continue; res[i][j] = (res[i][j] + aik * b[k][j]) % MOD; } } } return res; } } -
class Solution { public: int zigZagArrays(int n, int l, int r) { const int mod = 1e9 + 7; int m = r - l + 1; int size = 2 * m; vector<vector<long long>> trans(size, vector<long long>(size)); for (int x = 0; x < m; ++x) { for (int y = 0; y < x; ++y) { trans[y][m + x] = 1; } } for (int x = 0; x < m; ++x) { for (int y = x + 1; y < m; ++y) { trans[m + y][x] = 1; } } auto power = matrixPow(trans, n - 1, mod); vector<long long> init(size, 1); auto result = multiply(power, init, mod); long long ans = 0; for (long long v : result) { ans = (ans + v) % mod; } return ans; } private: vector<long long> multiply(vector<vector<long long>>& mat, vector<long long>& vec, int mod) { int n = mat.size(); vector<long long> res(n); for (int i = 0; i < n; ++i) { long long sum = 0; for (int j = 0; j < n; ++j) { sum = (sum + mat[i][j] * vec[j]) % mod; } res[i] = sum; } return res; } vector<vector<long long>> multiply( vector<vector<long long>>& a, vector<vector<long long>>& b, int mod) { int n = a.size(); vector<vector<long long>> res(n, vector<long long>(n)); for (int i = 0; i < n; ++i) { for (int k = 0; k < n; ++k) { if (a[i][k] == 0) { continue; } long long aik = a[i][k]; for (int j = 0; j < n; ++j) { if (b[k][j] == 0) { continue; } res[i][j] = (res[i][j] + aik * b[k][j]) % mod; } } } return res; } vector<vector<long long>> matrixPow(vector<vector<long long>>& mat, long long exp, int mod) { int n = mat.size(); vector<vector<long long>> res(n, vector<long long>(n)); for (int i = 0; i < n; ++i) { res[i][i] = 1; } while (exp > 0) { if (exp & 1) { res = multiply(res, mat, mod); } mat = multiply(mat, mat, mod); exp >>= 1; } return res; } }; -
class Solution: def zigZagArrays(self, n: int, l: int, r: int) -> int: mod = 10**9 + 7 m = r - l + 1 size = 2 * m trans = [[0] * size for _ in range(size)] for x in range(m): for y in range(x): trans[y][m + x] = 1 for x in range(m): for y in range(x + 1, m): trans[m + y][x] = 1 def mul_mat(a, b): res = [[0] * size for _ in range(size)] for i in range(size): for k in range(size): if a[i][k] == 0: continue aik = a[i][k] for j in range(size): if b[k][j]: res[i][j] = (res[i][j] + aik * b[k][j]) % mod return res def mul_vec(mat, vec): res = [0] * size for i in range(size): s = 0 for j in range(size): s = (s + mat[i][j] * vec[j]) % mod res[i] = s return res power = [[int(i == j) for j in range(size)] for i in range(size)] exp = n - 1 while exp: if exp & 1: power = mul_mat(power, trans) trans = mul_mat(trans, trans) exp >>= 1 init = [1] * size return sum(mul_vec(power, init)) % mod -
func zigZagArrays(n int, l int, r int) int { const mod = 1_000_000_007 m := r - l + 1 size := 2 * m trans := make([][]int, size) for i := range trans { trans[i] = make([]int, size) } for x := 0; x < m; x++ { for y := 0; y < x; y++ { trans[y][m+x] = 1 } } for x := 0; x < m; x++ { for y := x + 1; y < m; y++ { trans[m+y][x] = 1 } } power := matrixPow(trans, n-1, mod) init := make([]int, size) for i := range init { init[i] = 1 } result := mulVec(power, init, mod) ans := 0 for _, v := range result { ans = (ans + v) % mod } return ans } func mulVec(mat [][]int, vec []int, mod int) []int { n := len(mat) res := make([]int, n) for i := 0; i < n; i++ { sum := 0 for j := 0; j < n; j++ { sum = (sum + mat[i][j]*vec[j]) % mod } res[i] = sum } return res } func mulMat(a, b [][]int, mod int) [][]int { n := len(a) res := make([][]int, n) for i := range res { res[i] = make([]int, n) } for i := 0; i < n; i++ { for k := 0; k < n; k++ { if a[i][k] == 0 { continue } aik := a[i][k] for j := 0; j < n; j++ { if b[k][j] == 0 { continue } res[i][j] = (res[i][j] + aik*b[k][j]) % mod } } } return res } func matrixPow(mat [][]int, exp int, mod int) [][]int { n := len(mat) res := make([][]int, n) for i := range res { res[i] = make([]int, n) res[i][i] = 1 } for exp > 0 { if exp&1 == 1 { res = mulMat(res, mat, mod) } mat = mulMat(mat, mat, mod) exp >>= 1 } return res }