diff --git a/1298-maximum-candies-you-can-get-from-boxes.js b/1298-maximum-candies-you-can-get-from-boxes.js new file mode 100644 index 0000000..b14f63d --- /dev/null +++ b/1298-maximum-candies-you-can-get-from-boxes.js @@ -0,0 +1,28 @@ +/** + * @param {number[]} status + * @param {number[]} candies + * @param {number[][]} keys + * @param {number[][]} containedBoxes + * @param {number[]} initialBoxes + * @return {number} + */ +var maxCandies = function(status, candies, keys, containedBoxes, initialBoxes) { + let foundOpenable = true; + let totalCandies = 0; + while (initialBoxes.length > 0 && foundOpenable) { + foundOpenable = false; + let nextBoxes = []; + for (let boxId of initialBoxes) { + if (status[boxId]) { + foundOpenable = true; + nextBoxes.push(...containedBoxes[boxId]); + for (let keyId of keys[boxId]) status[keyId] = 1; + totalCandies += candies[boxId]; + } else { + nextBoxes.push(boxId); + } + } + initialBoxes = nextBoxes; + } + return totalCandies; +}; diff --git a/2045-second-minimum-time-to-reach-destination.js b/2045-second-minimum-time-to-reach-destination.js index bec00ca..8bb74c3 100644 --- a/2045-second-minimum-time-to-reach-destination.js +++ b/2045-second-minimum-time-to-reach-destination.js @@ -1,16 +1,3 @@ -const initializeGraph = (n) => { - let G = [] - for (let i = 0; i < n; i++) { - G.push([]) - } - return G -} -const addEdgeToG = (G, Edges) => { - for (const [u, v] of Edges) { - G[u].push(v) - G[v].push(u) - } -} /** * @param {number} n * @param {number[][]} edges @@ -18,15 +5,15 @@ const addEdgeToG = (G, Edges) => { * @param {number} change * @return {number} */ -const secondMinimum = (n, edges, time, change) => { +var secondMinimum = function(n, edges, time, change) { let adj = initializeGraph(n + 1) addEdgeToG(adj, edges) let cost = initializeGraph(n + 1) - let pq = new MinPriorityQueue({ priority: (x) => x[0] }) - pq.enqueue([0, 1]) + let pq = new PQ((a, b) => a[0] < b[0]) + pq.push([0, 1]) let green = 2 * change while (pq.size()) { - let cur = pq.dequeue().element + let cur = pq.pop() let [t, node] = cur if (cost[node].length == 2) continue let nextT = @@ -45,9 +32,89 @@ const secondMinimum = (n, edges, time, change) => { continue } } - for (const next_node of adj[node]) pq.enqueue([nextT + time, next_node]) + for (const next_node of adj[node]) pq.push([nextT + time, next_node]) } return cost[n][1] +}; +function initializeGraph(n) { + let G = [] + for (let i = 0; i < n; i++) { + G.push([]) + } + return G +} +function addEdgeToG(G, Edges) { + for (const [u, v] of Edges) { + G[u].push(v) + G[v].push(u) + } +} +class PQ { + constructor(comparator = (a, b) => a > b) { + this.heap = [] + this.top = 0 + this.comparator = comparator + } + size() { + return this.heap.length + } + isEmpty() { + return this.size() === 0 + } + peek() { + return this.heap[this.top] + } + push(...values) { + values.forEach((value) => { + this.heap.push(value) + this.siftUp() + }) + return this.size() + } + pop() { + const poppedValue = this.peek() + const bottom = this.size() - 1 + if (bottom > this.top) { + this.swap(this.top, bottom) + } + this.heap.pop() + this.siftDown() + return poppedValue + } + replace(value) { + const replacedValue = this.peek() + this.heap[this.top] = value + this.siftDown() + return replacedValue + } + + parent = (i) => ((i + 1) >>> 1) - 1 + left = (i) => (i << 1) + 1 + right = (i) => (i + 1) << 1 + greater = (i, j) => this.comparator(this.heap[i], this.heap[j]) + swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]]) + siftUp = () => { + let node = this.size() - 1 + while (node > this.top && this.greater(node, this.parent(node))) { + this.swap(node, this.parent(node)) + node = this.parent(node) + } + } + siftDown = () => { + let node = this.top + while ( + (this.left(node) < this.size() && this.greater(this.left(node), node)) || + (this.right(node) < this.size() && this.greater(this.right(node), node)) + ) { + let maxChild = + this.right(node) < this.size() && + this.greater(this.right(node), this.left(node)) + ? this.right(node) + : this.left(node) + this.swap(node, maxChild) + node = maxChild + } + } } // another diff --git a/2513-minimize-the-maximum-of-two-arrays.js b/2513-minimize-the-maximum-of-two-arrays.js new file mode 100644 index 0000000..b894fd3 --- /dev/null +++ b/2513-minimize-the-maximum-of-two-arrays.js @@ -0,0 +1,42 @@ +/** + * @param {number} divisor1 + * @param {number} divisor2 + * @param {number} uniqueCnt1 + * @param {number} uniqueCnt2 + * @return {number} + */ +var minimizeSet = function(divisor1, divisor2, uniqueCnt1, uniqueCnt2) { + let l = 1, r = 1e18 + const {floor: flr} = Math + while(l < r) { + const mid = l + flr((r - l) / 2) + if(notEnough(mid)) l = mid + 1 + else r = mid + } + return l + + + function notEnough(n) { + const a = n - flr(n / divisor1) + const b = n - flr(n / divisor2) + const c = n - (flr(n / divisor1) + flr(n / divisor2) - flr( n / lcm(divisor1, divisor2))) + if(a < uniqueCnt1) return true + if(b < uniqueCnt2) return true + if(a + b - c < uniqueCnt1 + uniqueCnt2) return true + return false + } +}; + +function gcd(a, b) { + while (b !== 0) { + [a, b] = [b, a % b]; + } + return a; +} + +function lcm(a, b) { + return (a / gcd(a, b)) * b; +} + + + diff --git a/2528-maximize-the-minimum-powered-city.js b/2528-maximize-the-minimum-powered-city.js new file mode 100644 index 0000000..59d10ff --- /dev/null +++ b/2528-maximize-the-minimum-powered-city.js @@ -0,0 +1,38 @@ +/** + * @param {number[]} stations + * @param {number} r + * @param {number} k + * @return {number} + */ +var maxPower = function(stations, r, k) { + let lo = 0, hi = Number.MAX_SAFE_INTEGER + const { floor: flr, min } = Math + const n = stations.length + while(lo < hi) { + const mid = hi - flr((hi - lo) / 2) + if(isOk(stations.slice(0),k, mid)) lo = mid + else hi = mid - 1 + } + + return lo + + function isOk(sc,k, m) { + let sum = 0 + for(let i = 0; i < min(n, r); i++) { + sum += sc[i] + } + for(let i = 0; i < n; i++) { + if(i + r < n) sum += sc[i + r] + if(i - r - 1 >= 0) sum -= sc[i - r - 1] + if(sum >= m) continue + const diff = m - sum + if(k < diff) return false + sc[min(n - 1, i + r)] += diff + sum = m + k -= diff + } + + return true + } + +}; diff --git a/2563-count-the-number-of-fair-pairs.js b/2563-count-the-number-of-fair-pairs.js index 3bdf077..3db0636 100644 --- a/2563-count-the-number-of-fair-pairs.js +++ b/2563-count-the-number-of-fair-pairs.js @@ -38,3 +38,32 @@ function low(arr, target) { } return count; } + +// another + +/** + * @param {number[]} nums + * @param {number} lower + * @param {number} upper + * @return {number} + */ +const countFairPairs = function(nums, lower, upper) { + nums.sort((a, b) => a - b) + return lowerBound(nums, upper + 1) - lowerBound(nums, lower) +}; + +function lowerBound(nums, value) { + let l = 0, r = nums.length - 1 + let res = 0 + while(l < r) { + const sum = nums[l] + nums[r] + if(sum < value) { + res += r - l + l++ + } else { + r-- + } + } + + return res +} diff --git a/2659-make-array-empty.js b/2659-make-array-empty.js new file mode 100644 index 0000000..4bef4f3 --- /dev/null +++ b/2659-make-array-empty.js @@ -0,0 +1,23 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var countOperationsToEmptyArray = function(nums) { + const pos = new Map() + const n = nums.length + let res = n + + for (let i = 0; i < n; ++i) { + pos.set(nums[i], i) + } + + nums.sort((a, b) => a - b) + + for (let i = 1; i < n; ++i) { + if (pos.get(nums[i]) < pos.get(nums[i - 1])) { + res += n - i + } + } + + return res +}; diff --git a/2861-maximum-number-of-alloys.js b/2861-maximum-number-of-alloys.js index d5c0891..41c009e 100644 --- a/2861-maximum-number-of-alloys.js +++ b/2861-maximum-number-of-alloys.js @@ -7,40 +7,35 @@ * @param {number[]} cost * @return {number} */ -var maxNumberOfAlloys = function (n, k, budget, composition, stock, cost) { - let low = 1, +const maxNumberOfAlloys = function(n, k, budget, composition, stock, cost) { + let low = 0, high = 1e9 - let ans = 0 // intialise the ans = 0; + let res = 0 - while (low <= high) { - let mid = low + Math.floor((high - low) / 2) + while (low < high) { + let mid = high - Math.floor((high - low) / 2) if (isPossible(n, k, budget, composition, stock, cost, mid)) { - low = mid + 1 - ans = mid // we can form the "mid" quantity of alloys from any of the compositions in the given "budget"; + low = mid } else { high = mid - 1 } } - return ans -} + return low +}; + function isPossible(n, k, budget, composition, stock, costs, fixed_alloy) { for (let i = 0; i < k; i++) { let calBudget = 0 for (let j = 0; j < n; j++) { - // this much quantity of jth metal is required to form the "fixed_alloy"; let required = 1 * composition[i][j] * fixed_alloy - // subtracting the stocked portion of the jth metal; required -= stock[j] if (required > 0) { - // adding the cost for required quantity of jth metal to form the "fixed_alloy"; calBudget += 1 * required * costs[j] } } - // "fixed alloy can be formed with the ith machine"; if (calBudget <= 1 * budget) return true } - // can't be formed with any of the machine; return false } diff --git a/3007-maximum-number-that-sum-of-the-prices-is-less-than-or-equal-to-k.js b/3007-maximum-number-that-sum-of-the-prices-is-less-than-or-equal-to-k.js new file mode 100644 index 0000000..11d2678 --- /dev/null +++ b/3007-maximum-number-that-sum-of-the-prices-is-less-than-or-equal-to-k.js @@ -0,0 +1,35 @@ +/** + * @param {number} k + * @param {number} x + * @return {number} + */ +var findMaximumNumber = function(k, x) { + let l = 0n; + let r = 10n ** 20n; + + while (l + 1n < r) { + let m = (l + r) >> 1n; + + if (F(Number(m + 1n)) <= k) l = m; + else r = m; + } + + return Number(l); + + function F(m) { + let count = 0; + + for (let i = 1; i < 80; i++) { + let bit = (i * x) - 1; + let S = 1n << BigInt(bit); + let B = BigInt(m) / S; + + count += Number(S) * Math.floor(Number(B) / 2); + if ((Number(B) & 1) === 1) { + count += Number(BigInt(m) % S); + } + } + + return count; + } +}; diff --git a/3399-smallest-substring-with-identical-characters-ii.js b/3399-smallest-substring-with-identical-characters-ii.js new file mode 100644 index 0000000..ae74d5c --- /dev/null +++ b/3399-smallest-substring-with-identical-characters-ii.js @@ -0,0 +1,48 @@ +/** + * @param {string} s + * @param {number} numOps + * @return {number} + */ +var minLength = function (s, numOps) { + const arr = Array.from(s, Number) + + const L = groupLengths(arr) + + let l = 1, + r = 100000 + while (l < r) { + const m = Math.floor((l + r) / 2) + const need = check(arr, m) + if (need <= numOps) { + r = m + } else { + l = m + 1 + } + } + return l + + function check(A, k) { + if (k === 1) { + let res = 0 + for (let i = 0; i < A.length; i++) { + if (A[i] === i % 2) res++ + } + return Math.min(res, A.length - res) + } + return L.reduce((acc, l) => acc + Math.floor(l / (k + 1)), 0) + } + + function groupLengths(arr) { + const lengths = [] + let count = 1 + for (let i = 1; i <= arr.length; i++) { + if (i < arr.length && arr[i] === arr[i - 1]) { + count++ + } else { + lengths.push(count) + count = 1 + } + } + return lengths + } +} diff --git a/3449-maximize-the-minimum-game-score.js b/3449-maximize-the-minimum-game-score.js new file mode 100644 index 0000000..abd1f14 --- /dev/null +++ b/3449-maximize-the-minimum-game-score.js @@ -0,0 +1,44 @@ +/** + * @param {number[]} points + * @param {number} m + * @return {number} + */ +var maxScore = function (points, m) { + const n = points.length + if (m < n) return 0 + + const can = (val) => { + let total = 0, + transfer = 0, + skipAdd = 0 + for (let i = 0; i < n && total <= m; i++) { + const point = points[i] + const necessary = Math.floor((val + point - 1) / point) + if (transfer >= necessary) { + transfer = 0 + skipAdd++ + } else { + const p = transfer * point + const ops = Math.floor((val - p + point - 1) / point) + total += 2 * ops - 1 + total += skipAdd + + transfer = Math.max(ops - 1, 0) + skipAdd = 0 + } + } + return total <= m + } + + let l = 1n, + r = 10n ** 15n + while (l < r) { + const mid = r - (r - l) / 2n + if (can(Number(mid))) { + l = mid + } else { + r = mid - 1n + } + } + return Number(l) +} diff --git a/3464-maximize-the-distance-between-points-on-a-square.js b/3464-maximize-the-distance-between-points-on-a-square.js index 47fcde2..57f343d 100644 --- a/3464-maximize-the-distance-between-points-on-a-square.js +++ b/3464-maximize-the-distance-between-points-on-a-square.js @@ -1,3 +1,88 @@ +/** + * @param {number} side + * @param {number[][]} points + * @param {number} k + * @return {number} + */ +const maxDistance = function (side, points, k) { + const n = points.length + const arr = [] + + const next = new Array(15000) + + for (const p of points) { + if (p[0] === 0) { + arr.push(p[1]) + } else if (p[1] === side) { + arr.push(side + p[0]) + } else if (p[0] === side) { + arr.push(2 * side + side - p[1]) + } else if (p[1] === 0) { + arr.push(3 * side + side - p[0]) + } + } + + arr.sort((a, b) => a - b) + + let low = 0, + high = side + while (low < high) { + const mid = high - Math.floor((high - low) / 2) + if (isOK(mid, k)) { + low = mid + } else { + high = mid - 1 + } + } + return low + + function isOK(dist, k) { + let j = 0 + for (let i = 0; i < n; i++) { + while (pos(j) - arr[i] < dist) { + j++ + } + next[i] = j + } + + for (let i = 0; i < n; i++) { + let flag = true + let cur = i + for (let t = 0; t < k - 1; t++) { + if (cur < n) { + cur = next[cur] + } else { + cur = next[cur % n] + n + } + if (cur >= i + n) { + flag = false + break + } + } + if (pos(i) - pos(cur % n) < dist) { + flag = false + } + if (flag) { + return true + } + } + return false + } + + function pos(j) { + if (j < n) { + return arr[j] + } else { + return arr[j % n] + side * 4 + } + } + +} + + +// another + + /** * @param {number} side * @param {number[][]} points diff --git a/3552-grid-teleportation-traversal.js b/3552-grid-teleportation-traversal.js new file mode 100644 index 0000000..a10f3a3 --- /dev/null +++ b/3552-grid-teleportation-traversal.js @@ -0,0 +1,148 @@ +/** + * @param {string[]} matrix + * @return {number} + */ +var minMoves = function (matrix) { + const n = matrix.length, + m = matrix[0].length + + const cells = {} + for (let i = 0; i < n; i++) { + for (let j = 0; j < m; j++) { + if (matrix[i][j] !== '.' && matrix[i][j] !== '#') { + if (!cells[matrix[i][j]]) { + cells[matrix[i][j]] = [] + } + cells[matrix[i][j]].push([i, j]) + } + } + } + + if (matrix[n - 1][m - 1] === '#') return -1 + + const pq = new PQ((a, b) => a[0] < b[0]) + const dist = Array.from({ length: n }, () => Array(m).fill(Infinity)) + const used = new Set() + + pq.push([0, 0, 0]) + dist[0][0] = 0 + + const dx = [0, 0, -1, 1] + const dy = [-1, 1, 0, 0] + + while (!pq.isEmpty()) { + const [curDist, x, y] = pq.pop() + + if (curDist > dist[x][y]) continue + if (x === n - 1 && y === m - 1) return curDist + + if ( + isUpper(matrix[x][y]) && + !used.has(matrix[x][y]) + ) { + used.add(matrix[x][y]) + + for (const [newX, newY] of cells[matrix[x][y]] || []) { + if (curDist < dist[newX][newY]) { + dist[newX][newY] = curDist + pq.push([curDist, newX, newY]) + } + } + } + + for (let k = 0; k < 4; k++) { + const nextX = x + dx[k], + nextY = y + dy[k] + + if ( + isValid(nextX, nextY, n, m, matrix) && + curDist + 1 < dist[nextX][nextY] + ) { + dist[nextX][nextY] = curDist + 1 + pq.push([curDist + 1, nextX, nextY]) + } + } + } + + return -1 +} + +function isUpper(ch) { + const A = 'A'.charCodeAt(0) + const Z = 'Z'.charCodeAt(0) + const code = ch.charCodeAt(0) + return code >= A && code <= Z +} +function isValid(i, j, n, m, matrix) { + if (i < 0 || j < 0 || i >= n || j >= m) return false + if (matrix[i][j] === '#') return false + return true +} + +class PQ { + constructor(comparator = (a, b) => a > b) { + this.heap = [] + this.top = 0 + this.comparator = comparator + } + size() { + return this.heap.length + } + isEmpty() { + return this.size() === 0 + } + peek() { + return this.heap[this.top] + } + push(...values) { + values.forEach((value) => { + this.heap.push(value) + this.siftUp() + }) + return this.size() + } + pop() { + const poppedValue = this.peek() + const bottom = this.size() - 1 + if (bottom > this.top) { + this.swap(this.top, bottom) + } + this.heap.pop() + this.siftDown() + return poppedValue + } + replace(value) { + const replacedValue = this.peek() + this.heap[this.top] = value + this.siftDown() + return replacedValue + } + + parent = (i) => ((i + 1) >>> 1) - 1 + left = (i) => (i << 1) + 1 + right = (i) => (i + 1) << 1 + greater = (i, j) => this.comparator(this.heap[i], this.heap[j]) + swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]]) + siftUp = () => { + let node = this.size() - 1 + while (node > this.top && this.greater(node, this.parent(node))) { + this.swap(node, this.parent(node)) + node = this.parent(node) + } + } + siftDown = () => { + let node = this.top + while ( + (this.left(node) < this.size() && this.greater(this.left(node), node)) || + (this.right(node) < this.size() && this.greater(this.right(node), node)) + ) { + let maxChild = + this.right(node) < this.size() && + this.greater(this.right(node), this.left(node)) + ? this.right(node) + : this.left(node) + this.swap(node, maxChild) + node = maxChild + } + } +} diff --git a/3579-minimum-steps-to-convert-string-with-operations.js b/3579-minimum-steps-to-convert-string-with-operations.js new file mode 100644 index 0000000..2b1ce37 --- /dev/null +++ b/3579-minimum-steps-to-convert-string-with-operations.js @@ -0,0 +1,54 @@ +/** + * @param {string} word1 + * @param {string} word2 + * @return {number} + */ +var minOperations = function (word1, word2) { + const arr1 = word1.split('') + const arr2 = word2.split('') + const n = arr1.length + const dp = Array.from({ length: n }, () => Array(n).fill(null)) + const res = solve(0, 0, arr1, arr2, n, dp) + return res +} + +function solve(i, j, arr1, arr2, n, dp) { + if (i >= n) return 0 + if (j >= n) return 100000 + + if (dp[i][j] !== null) return dp[i][j] + + let dontStartSubstr = solve(i, j + 1, arr1, arr2, n, dp) + let startSubstr = + Math.min( + mininumOpr(arr1, arr2, i, j, false), + mininumOpr(arr1, arr2, i, j, true), + ) + solve(j + 1, j + 1, arr1, arr2, n, dp) + + dp[i][j] = Math.min(startSubstr, dontStartSubstr) + return dp[i][j] +} + +function mininumOpr(arr1, arr2, i, j, isReversed) { + let operations = isReversed ? 1 : 0 + let x = i + let idx = isReversed ? j : i + const mul = isReversed ? -1 : 1 + const freqOfMismatched = Array.from({ length: 26 }, () => Array(26).fill(0)) + + while (x <= j) { + if (arr1[x] !== arr2[idx]) { + const wanted = arr1[x].charCodeAt(0) - 97 + const got = arr2[idx].charCodeAt(0) - 97 + if (freqOfMismatched[got][wanted] > 0) { + freqOfMismatched[got][wanted]-- + } else { + freqOfMismatched[wanted][got]++ + operations++ + } + } + x++ + idx += mul + } + return operations +} diff --git a/3593-minimum-increments-to-equalize-leaf-paths.js b/3593-minimum-increments-to-equalize-leaf-paths.js index 6c4baea..0a9b47e 100644 --- a/3593-minimum-increments-to-equalize-leaf-paths.js +++ b/3593-minimum-increments-to-equalize-leaf-paths.js @@ -44,3 +44,43 @@ function dfs(node, parent, tree, cost, changes) { return cost[node] + maxCost } + + +// another + +/** + * @param {number} n + * @param {number[][]} edges + * @param {number[]} cost + * @return {number} + */ +var minIncrease = function(n, edges, cost) { + const g = {} + for(const [u, v] of edges) { + if(g[u] == null) g[u] = [] + if(g[v] == null) g[v] = [] + g[u].push(v) + g[v].push(u) + } + let res = 0 + + dfs(0, -1) + return res + + function dfs(i, f) { + const score = [] + for(let j of (g[i] || [])) { + if(j === f) continue + score.push(dfs(j, i)) + } + if(score.length === 0) return cost[i] + let ans = Math.max(...score) + + for(const v of score) { + if(ans > v) res++ + } + + return ans + cost[i] + } + +}; diff --git a/3608-minimum-time-for-k-connected-components.js b/3608-minimum-time-for-k-connected-components.js new file mode 100644 index 0000000..49e5105 --- /dev/null +++ b/3608-minimum-time-for-k-connected-components.js @@ -0,0 +1,41 @@ +/** + * @param {number} n + * @param {number[][]} edges + * @param {number} k + * @return {number} + */ +var minTime = function(n, edges, k) { + edges.sort((a, b) => b[2] - a[2]) + const uf = new UF(n) + let cnt = n + + for(let i = 0; i < edges.length; i++) { + const [u, v, t] = edges[i] + if(uf.union(u, v)) cnt-- + if(cnt < k) return t + } + return 0 +}; + +class UF { + constructor(n) { + this.root = Array(n).fill(null).map((_, i) => i) + } + find(x) { + if (this.root[x] !== x) { + this.root[x] = this.find(this.root[x]) + } + return this.root[x] + } + union(x, y) { + const xr = this.find(x) + const yr = this.find(y) + if(xr === yr) { + return false + } else { + this.root[yr] = xr + return true + } + + } +} diff --git a/3613-minimize-maximum-component-cost.js b/3613-minimize-maximum-component-cost.js new file mode 100644 index 0000000..6fe8a81 --- /dev/null +++ b/3613-minimize-maximum-component-cost.js @@ -0,0 +1,63 @@ +/** + * @param {number} n + * @param {number[][]} edges + * @param {number} k + * @return {number} + */ +const minCost = function(n, edges, k) { + const g = {}, {max, floor: flr} = Math + let low = 0, high = 1, res = 0 + + for(let i = 0; i < edges.length; i++) { + const [u, v, w] = edges[i] + if(g[u] == null) g[u] = [] + if(g[v] == null) g[v] = [] + g[u].push([v, w]) + g[v].push([u, w]) + high = max(high, w) + } + + while(low < high) { + const mid = flr((low + high) / 2) + if(isOK(g, mid, k)) { + high = mid + } else low = mid + 1 + } + + return low + + + function isOK(g, mid, k) { + const n = Object.keys(g).length + const adj = {} + + for(let i = 0; i < n; i++) { + if(g[i] == null) continue + for(const [nxt, w] of g[i]) { + if(adj[i] == null) adj[i] = [] + if(w <= mid) adj[i].push(nxt) + } + } + + const vis = Array(n).fill(false) + let c = 0 + + for(let i = 0; i < n; i++) { + if(!vis[i]) { + c++ + if(c > k) return false + dfs(adj, vis, i) + } + } + + return true + } + + function dfs(adj, vis, node) { + vis[node] = true + for(const nxt of (adj[node] || [])) { + if(!vis[nxt]) dfs(adj, vis, nxt) + } + } + +}; diff --git a/3620-network-recovery-pathways.js b/3620-network-recovery-pathways.js new file mode 100644 index 0000000..49326ce --- /dev/null +++ b/3620-network-recovery-pathways.js @@ -0,0 +1,103 @@ +/** + * @param {number[][]} edges + * @param {boolean[]} online + * @param {number} k + * @return {number} + */ +var findMaxPathScore = function (edges, online, k) { + const n = online.length + let adj_list + let in_degree + let max_edge_length + let topo_sort + + if (edges.length === 0) { + return -1 + } + + ;[adj_list, in_degree, max_edge_length] = create_adj_list() + topo_sort = find_toposort_order() + const res = binary_search(max_edge_length) + return res + + + function create_adj_list() { + const in_degree_original = new Array(n).fill(0) + let max_len = 0 + const adj = Array.from({ length: n }, () => []) + + for (const [u, v, cost] of edges) { + if (online[u] && online[v]) { + in_degree_original[v] += 1 + max_len = Math.max(max_len, cost) + adj[u].push([v, cost]) + } + } + return [adj, in_degree_original, max_len] + } + + function find_toposort_order() { + const dq = [] + const local_topo_sort = [] + + for (let node = 0; node < n; node++) { + if (in_degree[node] === 0) { + dq.push(node) + } + } + + while (dq.length > 0) { + const node = dq.shift() + local_topo_sort.push(node) + + for (const [adj, cost] of adj_list[node]) { + in_degree[adj] -= 1 + if (in_degree[adj] === 0) { + dq.push(adj) + } + } + } + + return local_topo_sort + } + + function check_feasibility_with_wt(min_edge_wt) { + const distances = new Array(n).fill(Infinity) + distances[0] = 0 + + for (const node of topo_sort) { + for (const [adj, cost] of adj_list[node]) { + if (cost < min_edge_wt) { + continue + } + + if (distances[node] + cost <= k) { + distances[adj] = Math.min(distances[adj], distances[node] + cost) + } + } + } + + if (distances[n - 1] <= k) { + return true + } else { + return false + } + } + + function binary_search(max_edge_length_param) { + let low = 0 + let high = Math.min(k, max_edge_length_param) + + while (low <= high) { + const mid = low + Math.floor((high - low) / 2) + + if (check_feasibility_with_wt(mid) === true) { + low = mid + 1 + } else { + high = mid - 1 + } + } + + return low - 1 + } +} diff --git a/3624-number-of-integers-with-popcount-depth-equal-to-k-ii.js b/3624-number-of-integers-with-popcount-depth-equal-to-k-ii.js new file mode 100644 index 0000000..b19c1c7 --- /dev/null +++ b/3624-number-of-integers-with-popcount-depth-equal-to-k-ii.js @@ -0,0 +1,120 @@ +/** + * @param {number[]} nums + * @param {number[][]} queries + * @return {number[]} + */ +var popcountDepth = function(nums, queries) { + let n = nums.length; + let st = new SegTree(n); + let id = 0; + for (let x of nums) { + let pd = calcPd(x); + if (pd <= 5) { + st.update(id, pd); + } + id++; + } + let res = []; + for (let v of queries) { + if (v[0] === 1) { + res.push(st.calc(v[1], v[2] + 1, v[3])); + } else { + let pd = calcPd(v[2]); + if (pd <= 5) { + st.update(v[1], pd); + } + } + } + return res +}; +class Node { + constructor(n) { + this.dep_mask = new Array(n).fill(0); + this._n = n; + } + + setPd(x) { + this.dep_mask = x; + } + + incPd(pd) { + this.dep_mask[pd]++; + } + + getPd() { + return this.dep_mask; + } + + getPdAt(id) { + return this.dep_mask[id]; + } + + clearPd() { + for (let i = 0; i < this._n; ++i) { + this.dep_mask[i] = 0; + } + } +} + +class SegTree { + constructor(n) { + this.sz = 1; + while (this.sz < n) { + this.sz *= 2; + } + this.T = new Array(2 * this.sz).fill(null).map(() => new Node(6)); + } + + mergePd(a, b) { + let c = new Array(6).fill(0); + for (let i = 0; i < 6; ++i) { + c[i] = a.dep_mask[i] + b.dep_mask[i]; + } + return c; + } + + update(id, pd) { + this.updateRec(0, 0, this.sz, id, pd); + } + + calc(l, r, k) { + return this.calcRec(0, 0, this.sz, l, r, k); + } + + updateRec(x, l, r, pos, pd) { + if ((r - l) === 1) { + this.T[x].clearPd(); + this.T[x].incPd(pd); + return; + } + let m = Math.floor((l + r) / 2); + if (pos < m) { + this.updateRec(2 * x + 1, l, m, pos, pd); + } else { + this.updateRec(2 * x + 2, m, r, pos, pd); + } + this.T[x].setPd(this.mergePd(this.T[2 * x + 1], this.T[2 * x + 2])); + } + + calcRec(x, l, r, ql, qr, req_pd) { + if (ql >= r || qr <= l) { + return 0; + } + if (l >= ql && r <= qr) { + return this.T[x].getPdAt(req_pd); + } + let m = Math.floor((l + r) / 2); + let le = this.calcRec(2 * x + 1, l, m, ql, qr, req_pd); + let ri = this.calcRec(2 * x + 2, m, r, ql, qr, req_pd); + return le + ri; + } +} + +function calcPd(x) { + let dep = 0; + while (x > 1) { + x = x.toString(2).split('').reduce((count, bit) => count + Number(bit), 0); + dep++; + } + return dep; +} diff --git a/3629-minimum-jumps-to-reach-end-via-prime-teleportation.js b/3629-minimum-jumps-to-reach-end-via-prime-teleportation.js new file mode 100644 index 0000000..6fb6bd9 --- /dev/null +++ b/3629-minimum-jumps-to-reach-end-via-prime-teleportation.js @@ -0,0 +1,64 @@ +const isPrime = new Array(1e6 + 1).fill(true); +/** + * @param {number[]} nums + * @return {number} + */ +var minJumps = function(nums) { + if (isPrime[0]) fill(); + const n = nums.length; + const maxi = Math.max(...nums); + const mp = new Map(); + + for (let i = 0; i < n; i++) { + if (!mp.has(nums[i])) { + mp.set(nums[i], []); + } + mp.get(nums[i]).push(i); + } + + const dist = new Array(n).fill(-1); + const qu = []; + qu.push(0); + dist[0] = 0; + const used = new Set(); + + while (qu.length > 0) { + const node = qu.shift(); + + if (node - 1 >= 0 && dist[node - 1] === -1) { + qu.push(node - 1); + dist[node - 1] = dist[node] + 1; + } + if (node + 1 < n && dist[node + 1] === -1) { + qu.push(node + 1); + dist[node + 1] = dist[node] + 1; + } + + if (!isPrime[nums[node]] || used.has(nums[node])) continue; + + for (let tar = nums[node]; tar <= maxi; tar += nums[node]) { + if (!mp.has(tar)) continue; + for (const it of mp.get(tar)) { + if (dist[it] !== -1) continue; + qu.push(it); + if (it === n - 1) return dist[node] + 1; + dist[it] = dist[node] + 1; + } + } + + used.add(nums[node]); + } + + return dist[dist.length - 1]; +}; + + +function fill() { + isPrime[0] = isPrime[1] = false; + for (let i = 2; i * i <= 1e6; ++i) { + if (isPrime[i]) { + for (let j = i * i; j <= 1e6; j += i) + isPrime[j] = false; + } + } +} diff --git a/3635-earliest-finish-time-for-land-and-water-rides-ii.js b/3635-earliest-finish-time-for-land-and-water-rides-ii.js new file mode 100644 index 0000000..3a6dcf8 --- /dev/null +++ b/3635-earliest-finish-time-for-land-and-water-rides-ii.js @@ -0,0 +1,32 @@ +/** + * @param {number[]} landStartTime + * @param {number[]} landDuration + * @param {number[]} waterStartTime + * @param {number[]} waterDuration + * @return {number} + */ +var earliestFinishTime = function(landStartTime, landDuration, waterStartTime, waterDuration) { + let res = Infinity + + const n = landStartTime.length + let minEnd = Infinity + for (let i = 0; i < n; i++) { + minEnd = Math.min(minEnd, landStartTime[i] + landDuration[i]) + } + const m = waterStartTime.length + + for (let i = 0; i < m; i++) { + res = Math.min(res, waterDuration[i] + Math.max(minEnd, waterStartTime[i])) + } + + minEnd = Infinity + for (let i = 0; i < m; i++) { + minEnd = Math.min(minEnd, waterStartTime[i] + waterDuration[i]) + } + + for (let i = 0; i < n; i++) { + res = Math.min(res, landDuration[i] + Math.max(minEnd, landStartTime[i])) + } + + return res +}; diff --git a/3637-trionic-array-i.js b/3637-trionic-array-i.js new file mode 100644 index 0000000..a9044bb --- /dev/null +++ b/3637-trionic-array-i.js @@ -0,0 +1,28 @@ +/** + * @param {number[]} nums + * @return {boolean} + */ +var isTrionic = function (nums) { + const n = nums.length + if (n < 3) return false + + let i = 0 + + while (i + 1 < n && nums[i] < nums[i + 1]) { + i++ + } + + const p = i + + while (i + 1 < n && nums[i] > nums[i + 1]) { + i++ + } + + const q = i + + while (i + 1 < n && nums[i] < nums[i + 1]) { + i++ + } + + return p > 0 && p < q && q < n - 1 && i === n - 1 +} diff --git a/3638-maximum-balanced-shipments.js b/3638-maximum-balanced-shipments.js new file mode 100644 index 0000000..a14031c --- /dev/null +++ b/3638-maximum-balanced-shipments.js @@ -0,0 +1,28 @@ +/** + * @param {number[]} weight + * @return {number} + */ +var maxBalancedShipments = function (weight) { + const n = weight.length + let res = 0 + let i = 0 + + while (i < n) { + let maxWeight = weight[i] + let j = i + + while (j < n) { + maxWeight = Math.max(maxWeight, weight[j]) + + if (weight[j] < maxWeight) { + res++ + break + } + j++ + } + + i = j === i ? i + 1 : j + 1 + } + + return res +} diff --git a/3639-minimum-time-to-activate-string.js b/3639-minimum-time-to-activate-string.js new file mode 100644 index 0000000..1110296 --- /dev/null +++ b/3639-minimum-time-to-activate-string.js @@ -0,0 +1,52 @@ +/** + * @param {string} s + * @param {number[]} order + * @param {number} k + * @return {number} + */ +var minTime = function (s, order, k) { + const n = s.length + + function f(mid) { + const st = s.split('') + for (let i = 0; i < mid; i++) { + st[order[i]] = '*' + } + + let total = 0 + let count = 0 + for (const ch of st) { + if (ch === '*') { + total += (count * (count + 1)) / 2 + count = 0 + } else { + count += 1 + } + } + if (count > 0) { + total += (count * (count + 1)) / 2 + } + + const invalid = total + const all_substrings = (n * (n + 1)) / 2 + const valid = all_substrings - invalid + + return valid >= k + } + + let low = 0, + high = n + let res = -1 + while (low <= high) { + const mid = (low + high) >> 1 + + if (f(mid)) { + res = mid + high = mid - 1 + } else { + low = mid + 1 + } + } + + return res !== -1 ? res - 1 : res +} diff --git a/3640-trionic-array-ii.js b/3640-trionic-array-ii.js new file mode 100644 index 0000000..d0a3b53 --- /dev/null +++ b/3640-trionic-array-ii.js @@ -0,0 +1,28 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var maxSumTrionic = function(nums) { + let n = nums.length, res = Number.MIN_SAFE_INTEGER, psum = nums[0]; + for (let l = 0, p = 0, q = 0, r = 1; r < nums.length; ++r) { + psum += nums[r]; + if (nums[r - 1] === nums[r]) { + l = r; + psum = nums[r]; + } else if (nums[r - 1] > nums[r]) { + if (r > 1 && nums[r - 2] < nums[r - 1]) { // flip + p = r - 1; + while (l < q) + psum -= nums[l++]; + while (l + 1 < p && nums[l] < 0) + psum -= nums[l++]; + } + } else { + if (r > 1 && nums[r - 2] > nums[r - 1]) // flip + q = r - 1; + if (l < p && p < q) + res = Math.max(res, psum); + } + } + return res; +}; diff --git a/3645-maximum-total-from-optimal-activation-order.js b/3645-maximum-total-from-optimal-activation-order.js new file mode 100644 index 0000000..ef3b0a3 --- /dev/null +++ b/3645-maximum-total-from-optimal-activation-order.js @@ -0,0 +1,26 @@ +/** + * @param {number[]} value + * @param {number[]} limit + * @return {number} + */ +var maxTotal = function(value, limit) { + const umap = new Map() + let res = 0 + const n = value.length + + for (let i = 0; i < n; i++) { + if (!umap.has(limit[i])) { + umap.set(limit[i], []) + } + umap.get(limit[i]).push(value[i]) + } + + for (const [lim, pq] of umap) { + pq.sort((a, b) => b - a); + for (let i = 0; i < lim && pq.length > 0; i++) { + res += pq.shift() + } + } + + return res +}; diff --git a/3652-best-time-to-buy-and-sell-stock-using-strategy.js b/3652-best-time-to-buy-and-sell-stock-using-strategy.js new file mode 100644 index 0000000..4395cd4 --- /dev/null +++ b/3652-best-time-to-buy-and-sell-stock-using-strategy.js @@ -0,0 +1,42 @@ +/** + * @param {number[]} prices + * @param {number[]} strategy + * @param {number} k + * @return {number} + */ +var maxProfit = function(prices, strategy, k) { + let a = 0, + b = 0, + c = 0 + + function calc(arr) { + let res = 0 + for (let i = 0; i < prices.length; i++) { + res += prices[i] * arr[i] + } + return res + } + + const n = strategy.length + const base = calc(strategy) + const h = Math.floor(k / 2) + const A = strategy.map((s, i) => -s * prices[i]) + const B = strategy.map((s, i) => (1 - s) * prices[i]) + const pA = new Array(n + 1).fill(0) + const pB = new Array(n + 1).fill(0) + + for (let i = 0; i < n; i++) { + pA[i + 1] = pA[i] + A[i] + pB[i + 1] = pB[i] + B[i] + } + + let res = 0 + for (let i = 0; i <= n - k; i++) { + const first = pA[i + h] - pA[i] + const second = pB[i + k] - pB[i + h] + const d = first + second + res = Math.max(d, res) + } + + return base + res +}; diff --git a/3653-xor-after-range-multiplication-queries-i.js b/3653-xor-after-range-multiplication-queries-i.js new file mode 100644 index 0000000..1817724 --- /dev/null +++ b/3653-xor-after-range-multiplication-queries-i.js @@ -0,0 +1,20 @@ +/** + * @param {number[]} nums + * @param {number[][]} queries + * @return {number} + */ +var xorAfterQueries = function (nums, queries) { + const mod = 10 ** 9 + 7 + for (const q of queries) { + let idx = q[0] + while (idx <= q[1]) { + nums[idx] = (nums[idx] * q[q.length - 1]) % mod + idx += q[2] + } + } + let res = nums[0] + for (let i = 1; i < nums.length; i++) { + res ^= nums[i] + } + return res +} diff --git a/3654-minimum-sum-after-divisible-sum-deletions.js b/3654-minimum-sum-after-divisible-sum-deletions.js new file mode 100644 index 0000000..e8c4ffb --- /dev/null +++ b/3654-minimum-sum-after-divisible-sum-deletions.js @@ -0,0 +1,30 @@ +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var minArraySum = function(nums, k) { + if (k === 1) return 0 + const n = nums.length + const total = nums.reduce((acc, num) => acc + num, 0) + const bestSoFar = new Array(k).fill(-1e20) + bestSoFar[0] = 0 + let prefixAcc = 0 + const dp = new Array(n).fill(0) + + for (let i = 0; i < nums.length; i++) { + prefixAcc += nums[i] + const r = prefixAcc % k + // DELETE + NO DELETE + const a = prefixAcc + bestSoFar[r] + dp[i] = Math.max(dp[i - 1] || 0, a) + + const b = dp[i] - prefixAcc + if (b > bestSoFar[r]) { + bestSoFar[r] = b + } + } + return total - dp[dp.length - 1] < 1e19 + ? total - dp[dp.length - 1] + : prefixAcc +}; diff --git a/3661-maximum-walls-destroyed-by-robots.js b/3661-maximum-walls-destroyed-by-robots.js new file mode 100644 index 0000000..95661fe --- /dev/null +++ b/3661-maximum-walls-destroyed-by-robots.js @@ -0,0 +1,62 @@ +/** + * @param {number[]} robots + * @param {number[]} distance + * @param {number[]} walls + * @return {number} + */ +var maxWalls = function(robots, distance, walls) { + const d = distance + const n = robots.length; + const x = new Array(n); + for (let i = 0; i < n; i++) x[i] = [robots[i], d[i]]; + walls.sort((a, b) => a - b); + x.sort((a, b) => a[0] - b[0]); + x.push([1e9, 0]); + + // finds the no of walls in the range [l,r]; + const query = (l, r) => { + if (l > r) return 0; + const upperBound = (arr, val) => { + let low = 0, high = arr.length; + while (low < high) { + const mid = (low + high) >> 1; + if (arr[mid] <= val) low = mid + 1; + else high = mid; + } + return low; + }; + const lowerBound = (arr, val) => { + let low = 0, high = arr.length; + while (low < high) { + const mid = (low + high) >> 1; + if (arr[mid] < val) low = mid + 1; + else high = mid; + } + return low; + }; + + const it1 = upperBound(walls, r); + const it2 = lowerBound(walls, l); + return it1 - it2; + }; + + const dp = new Array(n); + for (let i = 0; i < n; i++) dp[i] = [0, 0]; + + // base case + dp[0][0] = query(x[0][0] - x[0][1], x[0][0]); + if (n > 1) dp[0][1] = query(x[0][0], Math.min(x[1][0] - 1, x[0][0] + x[0][1])); + else dp[0][1] = query(x[0][0], x[0][0] + x[0][1]); + + // transition + for (let i = 1; i < n; i++) { + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0]) + query(x[i][0], Math.min(x[i + 1][0] - 1, x[i][0] + x[i][1])); + + dp[i][0] = dp[i - 1][0] + query(Math.max(x[i][0] - x[i][1], x[i - 1][0] + 1), x[i][0]); + const res = dp[i - 1][1] + + query(Math.max(x[i][0] - x[i][1], x[i - 1][0] + 1), x[i][0]) + - query(Math.max(x[i][0] - x[i][1], x[i - 1][0] + 1), Math.min(x[i - 1][0] + x[i - 1][1], x[i][0] - 1)); + dp[i][0] = Math.max(res, dp[i][0]); + } + return Math.max(dp[n - 1][0], dp[n - 1][1]); +}; diff --git a/3665-twisted-mirror-path-count.js b/3665-twisted-mirror-path-count.js new file mode 100644 index 0000000..4105152 --- /dev/null +++ b/3665-twisted-mirror-path-count.js @@ -0,0 +1,43 @@ +const mod = 1e9 + 7 +/** + * @param {number[][]} grid + * @return {number} + */ +var uniquePaths = function (grid) { + const n = grid.length + const m = grid[0].length + + const dp = Array.from({ length: n }, () => + Array.from({ length: m }, () => Array(2).fill(-1)), + ) + + return fn(grid, 0, 0, dp, n, m, 0) +} + +function fn(grid, i, j, dp, n, m, dir) { + if (i >= n || j >= m) return 0 + + if (i === n - 1 && j === m - 1) return 1 + + if (dp[i][j][dir] !== -1) return dp[i][j][dir] + + if (grid[i][j] === 1) { + if (dir === 1) { + return fn(grid, i + 1, j, dp, n, m, 0) + } else if (dir === 0) { + return fn(grid, i, j + 1, dp, n, m, 1) + } + } + + let move = 0 + if (j + 1 < m && (grid[i][j + 1] === 0 || grid[i][j + 1] === 1)) { + move += fn(grid, i, j + 1, dp, n, m, 1) + } + + if (i + 1 < n && (grid[i + 1][j] === 0 || grid[i + 1][j] === 1)) { + move += fn(grid, i + 1, j, dp, n, m, 0) + } + + dp[i][j][dir] = move % mod + return dp[i][j][dir] +} diff --git a/3666-minimum-operations-to-equalize-binary-string.js b/3666-minimum-operations-to-equalize-binary-string.js new file mode 100644 index 0000000..934378b --- /dev/null +++ b/3666-minimum-operations-to-equalize-binary-string.js @@ -0,0 +1,33 @@ +/** + * @param {string} s + * @param {number} k + * @return {number} + */ +var minOperations = function(s, k) { + const N = s.length; + const Z = [...s].filter(c => c === '0').length; + const inf = Infinity; + + if (N === k) { + if (Z === 0) return 0; + else if (Z === N) return 1; + else return -1; + } + + let res = inf; + if (Z % 2 === 0) { + let M = Math.max(ceil(Z, k), ceil(Z, N - k)); + M += M & 1; + res = Math.min(res, M); + } + if (Z % 2 === k % 2) { + let M = Math.max(ceil(Z, k), ceil(N - Z, N - k)); + M += (M & 1) === 0 ? 1 : 0; + res = Math.min(res, M); + } + + return res < inf ? res : -1; +}; +function ceil(x, y) { + return Math.floor((x + y - 1) / y); +} diff --git a/3670-maximum-product-of-two-integers-with-no-common-bits.js b/3670-maximum-product-of-two-integers-with-no-common-bits.js new file mode 100644 index 0000000..71773c2 --- /dev/null +++ b/3670-maximum-product-of-two-integers-with-no-common-bits.js @@ -0,0 +1,29 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var maxProduct = function(nums) { + const max_n = Math.max(...nums) + const msb = Math.floor(Math.log2(max_n)) + const maxMask = (1 << (msb + 1)) - 1 + const dp = new Array(maxMask + 1).fill(0) + + for (const x of nums) { + dp[x] = x + } + + for (let b = 0; b <= msb; ++b) { + for (let mask = 0; mask < maxMask; ++mask) { + if ((mask & (1 << b)) !== 0) { + dp[mask] = Math.max(dp[mask], dp[mask ^ (1 << b)]) + } + } + } + + let res = 0n + for (const n of nums) { + res = BigInt(Math.max(Number(res), n * dp[maxMask ^ n])) + } + + return Number(res) +}; diff --git a/3677-count-binary-palindromic-numbers.js b/3677-count-binary-palindromic-numbers.js new file mode 100644 index 0000000..19d1903 --- /dev/null +++ b/3677-count-binary-palindromic-numbers.js @@ -0,0 +1,125 @@ +/** + * @param {number} n + * @return {number} + */ +var countBinaryPalindromes = function (n) { + n = BigInt(n) + if (n === 0n) return 1 + const maxLen = Math.floor(Math.log2(Number(n))) + 1 + + let ret = 1n + for (let L = 1; L < maxLen; L++) { + const h = Math.floor((L + 1) / 2) + const mn = 1n << BigInt(h - 1) + const mx = (1n << BigInt(h)) - 1n + ret += mx - mn + 1n + } + + + const L = maxLen + const h = Math.floor((L + 1) / 2) + const mn = 1n << BigInt(h - 1) + const mx = (1n << BigInt(h)) - 1n + let lo = mn, + hi = mx + while (lo < hi) { + const mid = hi - (hi - lo) / 2n + const pal = build(mid, L) + if (pal <= n) { + lo = mid + } else { + hi = mid - 1n + } + } + const pal = build(hi, L) + if (pal <= n) ret += hi - mn + 1n + + + return Number(ret) +} +function reverseBits(x) { + let r = 0n + while (x > 0n) { + r = r * 2n + (x & 1n) + x >>= 1n + } + return r +} + +function build(half, L) { + const h = Math.floor((L + 1) / 2) + const k = L - h + if (L % 2 === 0) { + return (half << BigInt(k)) | reverseBits(half) + } else { + return (half << BigInt(k)) | reverseBits(half >> 1n) + } +} + + + +// another + + +/** + * @param {number} n + * @return {number} + */ +var countBinaryPalindromes = function (n) { + let dp = [] + let built = false + n = BigInt(n) + + if (!built) { + dp = new Array(56).fill(0) + dp[1] = 1 + dp[2] = 1 + for (let i = 3; i <= 55; i++) dp[i] = 2 * dp[i - 2] + built = true + } + + let maxbit = bit(n) + if (maxbit === -1) return 1 + let len = maxbit + 1 + + let count = 1 + for (let i = 1; i < len; i++) count += dp[i] + + let half = Math.floor((len + 1) / 2) + let start = 1n << BigInt(half - 1) + let end = (1n << BigInt(half)) - 1n + + let lo = start, + hi = end, + best = start - 1n + while (lo <= hi) { + let mid = (lo + hi) >> 1n + let pal = makePal(mid, len) + if (pal <= n) { + best = mid + lo = mid + 1n + } else { + hi = mid - 1n + } + } + + if (best >= start) count += Number(best - start + 1n) + return count + + function bit(num) { + for (let i = 63; i >= 0; i--) { + if ((num & (1n << BigInt(i))) !== 0n) return i + } + return -1 + } + + function makePal(p, len) { + let pal = p + let q = len % 2 === 0 ? p : p >> 1n + while (q > 0n) { + pal = (pal << 1n) | (q & 1n) + q >>= 1n + } + return pal + } +} diff --git a/3685-subsequence-sum-after-capping-elements.js b/3685-subsequence-sum-after-capping-elements.js new file mode 100644 index 0000000..5537123 --- /dev/null +++ b/3685-subsequence-sum-after-capping-elements.js @@ -0,0 +1,74 @@ +/** + * @param {number[]} nums + * @param {number} k + * @return {boolean[]} + */ +var subsequenceSumAfterCapping = function(nums, k) { + const n = nums.length + nums.sort((a, b) => a - b) + + const dp = Array.from({ length: n + 1 }, () => Array(k + 1).fill(false)) + + // Base cases + for (let i = 0; i <= n; i++) { + dp[i][0] = true + } + + // Classic subset-sum started + for (let i = 1; i <= n; i++) { + for (let j = 1; j <= k; j++) { + if (nums[i - 1] <= j) { + dp[i][j] = dp[i - 1][j - nums[i - 1]] || dp[i - 1][j] + } else { + dp[i][j] = dp[i - 1][j] + } + } + } + // Classic subset-sum finished + + const ans = [] + + // Helper function for upper_bound equivalent in JS + function upperBound(arr, target) { + let left = 0, + right = arr.length + while (left < right) { + const mid = Math.floor((left + right) / 2) + if (arr[mid] <= target) { + left = mid + 1 + } else { + right = mid + } + } + return left + } + + for (let x = 1; x <= n; x++) { + const it = upperBound(nums, x) + + if (it === nums.length) { + // if no element in nums is greater than x + ans.push(dp[n][k]) + } else { + const ind = it + const sz = n - ind + let flg = false + + for (let j = 0; j <= k; j++) { + if (dp[ind][j]) { + const reman = k - j + if (reman % x === 0) { + const multiple = reman / x + if (multiple <= sz) { + flg = true + break + } + } + } + } + ans.push(flg) + } + } + + return ans +}; diff --git a/3691-maximum-total-subarray-value-ii.js b/3691-maximum-total-subarray-value-ii.js new file mode 100644 index 0000000..89c56f1 --- /dev/null +++ b/3691-maximum-total-subarray-value-ii.js @@ -0,0 +1,80 @@ +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +const maxTotalValue = function (nums, k) { + const n = nums.length + const K = Math.floor(Math.log2(n)) + 1 + + const mn = Array.from({ length: n }, () => Array(K + 1).fill(Infinity)) + const mx = Array.from({ length: n }, () => Array(K + 1).fill(-Infinity)) + + for (let i = 0; i < n; i++) { + mn[i][0] = nums[i] + mx[i][0] = nums[i] + } + + for (let kk = 1; kk <= K; kk++) { + for (let i = 0; i + (1 << kk) - 1 < n; i++) { + mn[i][kk] = Math.min(mn[i][kk - 1], mn[i + (1 << (kk - 1))][kk - 1]) + mx[i][kk] = Math.max(mx[i][kk - 1], mx[i + (1 << (kk - 1))][kk - 1]) + } + } + + let lo = 0, + hi = 2e9 + while (lo < hi) { + const mid = hi - Math.floor((hi - lo) / 2) + if (count_ge(mid) >= k) { + lo = mid + } else { + hi = mid - 1 + } + } + const th = lo + + let ret_g = 0n + let count_g = 0n + for (let i = 0; i < n; i++) { + let l = i, + r = n - 1 + while (l < r) { + const mid = l + Math.floor((r - l) / 2) + if (GetDiff(i, mid) > th) { + r = mid + } else { + l = mid + 1 + } + } + if (GetDiff(i, r) > th) { + count_g += BigInt(n - r) + for (let j = r; j < n; j++) { + ret_g += BigInt(GetDiff(i, j)) + } + } + } + + const ret = ret_g + BigInt(th) * (BigInt(k) - count_g) + + return Number(ret) + + function GetDiff(L, R) { + const length = R - L + 1 + const k = Math.floor(Math.log2(length)) + return ( + Math.max(mx[L][k], mx[R - (1 << k) + 1][k]) - + Math.min(mn[L][k], mn[R - (1 << k) + 1][k]) + ) + } + + function count_ge(th) { + let count = 0 + let j = 0 + for (let i = 0; i < n; i++) { + while (j < n && GetDiff(i, j) < th) j++ + count += n - j + } + return count + } +} diff --git a/3696-minimum-time-to-activate-string.js b/3696-minimum-time-to-activate-string.js new file mode 100644 index 0000000..5430231 --- /dev/null +++ b/3696-minimum-time-to-activate-string.js @@ -0,0 +1,43 @@ +/** + * @param {string} s + * @param {number[]} order + * @param {number} k + * @return {number} + */ +var minTime = function(s, order, k) { + const len = order.length + let l = 0, r = len + const {floor: flr} = Math + while(l < r) { + const mid = flr((l + r) / 2) + if(isOK(mid)) r = mid + else l = mid + 1 + } + + return l >= len ? -1 : l + + function isOK(t) { + const n = s.length + + const isStar = Array(n).fill(false) + let inValid = 0, segLen = 0 + + for(let i = 0; i <= t; i++) isStar[order[i]] = true + + for(let i = 0; i < n; i++) { + if(isStar[i]) { + inValid += segLen * (segLen + 1) / 2 + segLen = 0 + } else { + segLen++ + } + } + + if(segLen) inValid += segLen * (segLen + 1) / 2 + + const all = n * (n + 1) / 2 + + const valid = all - inValid + return valid >= k + } +}; diff --git a/3699-number-of-zigzag-arrays-i.js b/3699-number-of-zigzag-arrays-i.js new file mode 100644 index 0000000..54b15cc --- /dev/null +++ b/3699-number-of-zigzag-arrays-i.js @@ -0,0 +1,28 @@ +/** + * @param {number} n + * @param {number} l + * @param {number} r + * @return {number} + */ +var zigZagArrays = function(n, l, r) { + r -= l; + let dp = new Array(r + 1).fill(1); + const mod = 10 ** 9 + 7; + for (let i = 1; i < n; i++) { + let pre = 0; + if (i & 1) { + for (let v = 0; v <= r; v++) { + let pre2 = pre + dp[v]; + dp[v] = pre; + pre = pre2 % mod; + } + } else { + for (let v = r; v >= 0; v--) { + let pre2 = pre + dp[v]; + dp[v] = pre; + pre = pre2 % mod; + } + } + } + return (dp.reduce((a, b) => a + b, 0) * 2) % mod; +}; diff --git a/3709-design-exam-scores-tracker.js b/3709-design-exam-scores-tracker.js new file mode 100644 index 0000000..ecad318 --- /dev/null +++ b/3709-design-exam-scores-tracker.js @@ -0,0 +1,44 @@ +var ExamTracker = function() { + this.time = [] + this.score = [] +}; + +/** + * @param {number} time + * @param {number} score + * @return {void} + */ +ExamTracker.prototype.record = function(time, score) { + this.time.push(time) + this.score.push(this.score.length ? this.score[this.score.length - 1] + score : score) + // console.log(this.score) +}; + +/** + * @param {number} startTime + * @param {number} endTime + * @return {number} + */ +ExamTracker.prototype.totalScore = function(startTime, endTime) { + const pre = bs(this.time, startTime - 1), cur = bs(this.time, endTime) + if(cur === -1) return 0 + return this.score[cur] - (pre === -1 ? 0 : this.score[pre]) +}; +// <= +function bs(arr, time) { + let l = -1, r = arr.length - 1 + while(l < r) { + const mid = r - Math.floor((r - l) / 2) + if(arr[mid] <= time) { + l = mid + } else r = mid - 1 + } + return l +} + +/** + * Your ExamTracker object will be instantiated and called as such: + * var obj = new ExamTracker() + * obj.record(time,score) + * var param_2 = obj.totalScore(startTime,endTime) + */ diff --git a/3733-minimum-time-to-complete-all-deliveries.js b/3733-minimum-time-to-complete-all-deliveries.js new file mode 100644 index 0000000..13972da --- /dev/null +++ b/3733-minimum-time-to-complete-all-deliveries.js @@ -0,0 +1,34 @@ +/** + * @param {number[]} d + * @param {number[]} r + * @return {number} + */ +var minimumTime = function (d, r) { + const [d0, d1] = d, [r0, r1] = r + let low = d0 + d1, hi = 2 * low * 2 + const lcm = r0 * r1 / gcd(r0, r1) + const {floor: flr} = Math + + while(low < hi) { + const mid = low + flr((hi - low) / 2) + if(isOK(mid)) { + hi = mid + } else low = mid + 1 + } + + return low + + function isOK(t) { + const s0 = t - flr(t / r0), s1 = t - flr(t / r1) + const total = t - flr(t / lcm) + if(s0 >= d0 && s1 >= d1 && total >= d0 + d1) { + return true + } + + return false + } +} + +function gcd(a, b) { + return b === 0 ? a : gcd(b, a % b) +} diff --git a/3745-maximize-expression-of-three-elements.js b/3745-maximize-expression-of-three-elements.js new file mode 100644 index 0000000..fcc2452 --- /dev/null +++ b/3745-maximize-expression-of-three-elements.js @@ -0,0 +1,18 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var maximizeExpressionOfThree = function(nums) { + const n = nums.length + let res = -Infinity + for(let i = 0; i < n - 2; i++) { + for(let j = i + 1; j < n - 1; j++) { + for(let k = j + 1; k < n; k++) { + res = Math.max(res, nums[i] + nums[j] - nums[k]) + res = Math.max(res, nums[i] - nums[j] + nums[k]) + res = Math.max(res, -nums[i] + nums[j] + nums[k]) + } + } + } + return res +}; diff --git a/3746-minimum-string-length-after-balanced-removals.js b/3746-minimum-string-length-after-balanced-removals.js new file mode 100644 index 0000000..13524d6 --- /dev/null +++ b/3746-minimum-string-length-after-balanced-removals.js @@ -0,0 +1,21 @@ +/** + * @param {string} s + * @return {number} + */ +var minLengthAfterRemovals = function(s) { + let a = 0, b = 0 + const n = s.length + let res = n + for(let i = 0; i < n; i++) { + const e = s[i] + if(e === 'a') a++ + else if(e === 'b') b++ + if(a > 0 && b > 0) { + const tmp = Math.min(a, b) + a -= tmp + b -= tmp + res -= tmp * 2 + } + } + return res +}; diff --git a/3747-count-distinct-integers-after-removing-zeros.js b/3747-count-distinct-integers-after-removing-zeros.js new file mode 100644 index 0000000..cb40cc4 --- /dev/null +++ b/3747-count-distinct-integers-after-removing-zeros.js @@ -0,0 +1,26 @@ +/** + * @param {number} n + * @return {number} + */ +var countDistinct = function(n) { + const s = '' + n + const d = s.length + const {pow} = Math + let total = 0 + for(let i = 1; i < d; i++) { + total += pow(9, i) + } + + for(let i = 0; i < d; i++) { + const e = +s[i] + let remaining = d - i - 1 + + if(e > 1) { + total += (e - 1) * pow(9, remaining) + } + if(e === 0) return total + } + + + return total + 1 +}; diff --git a/3748-count-stable-subarrays.js b/3748-count-stable-subarrays.js new file mode 100644 index 0000000..432130c --- /dev/null +++ b/3748-count-stable-subarrays.js @@ -0,0 +1,70 @@ +/** + * @param {number[]} nums + * @param {number[][]} queries + * @return {number[]} + */ +var countStableSubarrays = function(nums, queries) { + let n = nums.length + const {floor: flr} = Math + let res = [] + let segments = [], start = 0 + + for(let i = 0; i < n; i++) { + if(nums[i] < nums[i - 1]) { + segments.push([start, i - 1]) + start = i + } + } + segments.push([start, n - 1]) + + let pc = [] + + let total = 0 + for(const [s, e] of segments) { + let length = e - s + 1 + let count = length * (length + 1) / 2 + total += count + pc.push(total) + } + + for(const [l, r] of queries) { + let li = bisect(segments, l) - 1 + let ri = bisect(segments, r) - 1 + if(li < 0) li = 0 + if(ri < 0) ri = 0 + if(li === ri) { + let [ss, se] = segments[li] + let length = r - l + 1 + let count = length * (length + 1) / 2 + res.push(count) + } else { + let [ss, se] = segments[li] + let ll = se - l + 1 + let lc = ll * (ll + 1) / 2 + + let [ssr, ser] = segments[ri] + let rl = r - ssr + 1 + let rc = rl * (rl + 1) / 2 + + let mid_count = 0 + if(ri - li > 1) { + mid_count = pc[ri - 1] - pc[li] + } + res.push(lc + mid_count + rc) + } + + } + + return res + + function bisect(segments, x) { + let low = 0, high = segments.length + while(low < high) { + let mid = flr((low + high) / 2) + if(segments[mid][0] <= x) low = mid + 1 + else high = mid + } + + return low + } +}; diff --git a/3754-concatenate-non-zero-digits-and-multiply-by-sum-i.js b/3754-concatenate-non-zero-digits-and-multiply-by-sum-i.js new file mode 100644 index 0000000..2c98b5e --- /dev/null +++ b/3754-concatenate-non-zero-digits-and-multiply-by-sum-i.js @@ -0,0 +1,18 @@ +/** + * @param {number} n + * @return {number} + */ +var sumAndMultiply = function(n) { + const s = '' + n + let x = '', sum = 0 + for(const e of s) { + if(e === '0') continue + else { + x += e + sum += +e + } + } + x = +x + + return x * sum +}; diff --git a/3755-find-maximum-balanced-xor-subarray-length.js b/3755-find-maximum-balanced-xor-subarray-length.js new file mode 100644 index 0000000..055082b --- /dev/null +++ b/3755-find-maximum-balanced-xor-subarray-length.js @@ -0,0 +1,29 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var maxBalancedSubarray = function(nums) { + const hash = {} + let xor = 0, bal = 0, res = 0 + hash[k(0, 0)] = -1 + + for(let i = 0; i < nums.length; i++) { + const num = nums[i] + xor ^= num + if(num % 2 === 0) bal++ + else bal-- + if(hash[k(xor, bal)] != null) { + let tmp = i - hash[k(xor, bal)] + res = Math.max(res, tmp) + } else { + hash[k(xor, bal)] = i + } + } + + + return res + + function k(xor, bal) { + return `${xor},${bal}` + } +}; diff --git a/3756-concatenate-non-zero-digits-and-multiply-by-sum-ii.js b/3756-concatenate-non-zero-digits-and-multiply-by-sum-ii.js new file mode 100644 index 0000000..955491e --- /dev/null +++ b/3756-concatenate-non-zero-digits-and-multiply-by-sum-ii.js @@ -0,0 +1,56 @@ +/** + * @param {string} s + * @param {number[][]} queries + * @return {number[]} + */ +var sumAndMultiply = function (s, queries) { + const MOD = 1_000_000_007n + const n = s.length + + const idx = new Array(n + 1).fill(0) + const val = new Array(n + 1).fill(0n) + const tot = new Array(n + 1).fill(0n) + const pow10 = new Array(n + 1).fill(0n) + + pow10[0] = 1n + for (let i = 1; i <= n; i++) { + pow10[i] = (pow10[i - 1] * 10n) % MOD + } + + let c = 0 + + for (let i = 0; i < n; i++) { + const d = BigInt(s.charCodeAt(i) - '0'.charCodeAt(0)) + if (d !== 0n) { + c++ + val[c] = (val[c - 1] * 10n + d) % MOD + tot[c] = tot[c - 1] + d + } + idx[i + 1] = c + } + + const m = queries.length + const res = new Array(m) + + for (let i = 0; i < m; i++) { + const l = queries[i][0] + const r = queries[i][1] + + const a = idx[l] + const b = idx[r + 1] + + if (a === b) { + res[i] = 0 + continue + } + + const len = b - a + + const num = (val[b] - ((val[a] * pow10[len]) % MOD) + MOD) % MOD + const sumDigits = tot[b] - tot[a] + + res[i] = Number((num * sumDigits) % MOD) + } + + return res +} diff --git a/3757-number-of-effective-subsequences.js b/3757-number-of-effective-subsequences.js new file mode 100644 index 0000000..0797983 --- /dev/null +++ b/3757-number-of-effective-subsequences.js @@ -0,0 +1,64 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var countEffective = function (nums) { + const MOD = 1_000_000_007 + const n = nums.length + let T = 0 + for (const v of nums) T |= v + if (T === 0) return 0 + + const bits = [] + for (let b = 0; b < 20; ++b) { + if (((T >> b) & 1) !== 0) bits.push(b) + } + const M = bits.length + const S = 1 << M + const freq = new Array(S).fill(0) + + for (const v of nums) { + let m = 0 + for (let j = 0; j < M; ++j) { + if (((v >> bits[j]) & 1) !== 0) m |= 1 << j + } + freq[m]++ + } + + const F = freq.slice() + for (let i = 0; i < M; ++i) { + for (let mask = 0; mask < S; ++mask) { + if ((mask & (1 << i)) !== 0) { + F[mask] += F[mask ^ (1 << i)] + } + } + } + + const p2 = new Array(n + 1) + p2[0] = 1 + for (let i = 1; i <= n; ++i) { + p2[i] = (p2[i - 1] << 1) % MOD + } + + let ans = 0 + const all = S - 1 + for (let bmask = 1; bmask < S; ++bmask) { + const comp = all ^ bmask + const cnt = F[comp] + const add = p2[cnt] + if (countBits(bmask) % 2 === 1) ans = (ans + add) % MOD + else ans = (ans - add) % MOD + } + + ans = ((ans % MOD) + MOD) % MOD + return ans + + function countBits(x) { + let count = 0 + while (x > 0) { + count += x & 1 + x >>= 1 + } + return count + } +}