核心思路

与 Rust/Java 版本一致,使用矩阵快速幂加速 DP。

· 状态向量长度 2m(m = r-l+1 ≤ 75)
· 转移矩阵 T:
    newUp[i] = sum(down[0..i-1])
    newDown[i] = sum(up[i+1..m-1])
· 初始向量全为 1
· 答案 = sum(T^(n-1) * v) % MOD

---

JavaScript 实现

```javascript
/**
 * @param {number} n
 * @param {number} l
 * @param {number} r
 * @return {number}
 */
var zigZagArrays = function(n, l, r) {
    const MOD = 1000000007;
    const m = r - l + 1;
    const size = 2 * m;

    // 构建转移矩阵 T (size x size)
    const T = Array.from({ length: size }, () => Array(size).fill(0));
    for (let i = 0; i < m; i++) {
        // newUp[i] = sum(down[0..i-1])
        for (let j = 0; j < i; j++) {
            T[i][m + j] = 1;
        }
        // newDown[i] = sum(up[i+1..m-1])
        for (let j = i + 1; j < m; j++) {
            T[m + i][j] = 1;
        }
    }

    // 初始向量 (长度为1时,up和down全为1)
    const v = Array(size).fill(1);

    // 矩阵快速幂:计算 T^(n-1) * v
    const matMul = (A, B) => {
        const n = A.length;
        const C = Array.from({ length: n }, () => Array(n).fill(0));
        for (let i = 0; i < n; i++) {
            for (let k = 0; k < n; k++) {
                if (A[i][k] === 0) continue;
                const aik = A[i][k];
                const rowB = B[k];
                const rowC = C[i];
                for (let j = 0; j < n; j++) {
                    rowC[j] = (rowC[j] + aik * rowB[j]) % MOD;
                }
            }
        }
        return C;
    };

    const matVecMul = (A, vec) => {
        const n = A.length;
        const res = Array(n).fill(0);
        for (let i = 0; i < n; i++) {
            let sum = 0;
            const row = A[i];
            for (let j = 0; j < n; j++) {
                sum = (sum + row[j] * vec[j]) % MOD;
            }
            res[i] = sum;
        }
        return res;
    };

    // 快速幂
    let exp = n - 1;
    // 单位矩阵
    let resultMat = Array.from({ length: size }, () => Array(size).fill(0));
    for (let i = 0; i < size; i++) {
        resultMat[i][i] = 1;
    }
    let base = T;

    while (exp > 0) {
        if (exp & 1) {
            resultMat = matMul(resultMat, base);
        }
        base = matMul(base, base);
        exp >>= 1;
    }

    const resultVec = matVecMul(resultMat, v);
    let ans = 0;
    for (let val of resultVec) {
        ans = (ans + val) % MOD;
    }
    return ans;
};
```

---

更简洁版本(利用 BigInt 避免溢出)

由于 JS 中 Number 在乘法时可能溢出(MOD^2 ≈ 1e18,小于 Number.MAX_SAFE_INTEGER ≈ 9e15,实际会溢出),建议使用 BigInt 确保精度:

```javascript
var zigZagArrays = function(n, l, r) {
    const MOD = 1000000007n;
    const m = r - l + 1;
    const size = 2 * m;

    // 构建转移矩阵 (使用 BigInt)
    const T = Array.from({ length: size }, () => Array(size).fill(0n));
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < i; j++) T[i][m + j] = 1n;
        for (let j = i + 1; j < m; j++) T[m + i][j] = 1n;
    }

    const v = Array(size).fill(1n);

    const matMul = (A, B) => {
        const n = A.length;
        const C = Array.from({ length: n }, () => Array(n).fill(0n));
        for (let i = 0; i < n; i++) {
            for (let k = 0; k < n; k++) {
                if (A[i][k] === 0n) continue;
                const aik = A[i][k];
                const rowB = B[k];
                const rowC = C[i];
                for (let j = 0; j < n; j++) {
                    rowC[j] = (rowC[j] + aik * rowB[j]) % MOD;
                }
            }
        }
        return C;
    };

    const matVecMul = (A, vec) => {
        const n = A.length;
        const res = Array(n).fill(0n);
        for (let i = 0; i < n; i++) {
            let sum = 0n;
            const row = A[i];
            for (let j = 0; j < n; j++) {
                sum = (sum + row[j] * vec[j]) % MOD;
            }
            res[i] = sum;
        }
        return res;
    };

    let exp = n - 1;
    let resultMat = Array.from({ length: size }, () => Array(size).fill(0n));
    for (let i = 0; i < size; i++) resultMat[i][i] = 1n;
    let base = T;

    while (exp > 0) {
        if (exp & 1) resultMat = matMul(resultMat, base);
        base = matMul(base, base);
        exp >>= 1;
    }

    const resultVec = matVecMul(resultMat, v);
    let ans = 0n;
    for (let val of resultVec) ans = (ans + val) % MOD;
    return Number(ans);
};
```

---

复杂度

· 时间复杂度:O((2m)^3 \log n),m \le 75
· 空间复杂度:O(m^2)

示例

```javascript
console.log(zigZagArrays(3, 1, 3)); // 10
console.log(zigZagArrays(3, 4, 5)); // 2
```

 

更多推荐