diff --git a/src/main/kotlin/g3601_3700/s3618_split_array_by_prime_indices/Solution.kt b/src/main/kotlin/g3601_3700/s3618_split_array_by_prime_indices/Solution.kt new file mode 100644 index 00000000..5a86cb79 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3618_split_array_by_prime_indices/Solution.kt @@ -0,0 +1,57 @@ +package g3601_3700.s3618_split_array_by_prime_indices + +// #Medium #Array #Math #Number_Theory #Biweekly_Contest_161 +// #2025_07_22_Time_6_ms_(100.00%)_Space_78.20_MB_(81.48%) + +import kotlin.math.abs + +class Solution { + fun splitArray(nums: IntArray): Long { + val n = nums.size + val isPrime = sieve(n) + var sumA: Long = 0 + var sumB: Long = 0 + for (i in 0.. 2) { + isPrime[2] = true + } + run { + var i = 3 + while (i < n) { + isPrime[i] = true + i += 2 + } + } + if (n > 2) { + isPrime[2] = true + } + var i = 3 + while (i * i < n) { + if (isPrime[i]) { + var j = i * i + while (j < n) { + isPrime[j] = false + j += i * 2 + } + } + i += 2 + } + isPrime[0] = false + if (n > 1) { + isPrime[1] = false + } + return isPrime + } +} diff --git a/src/main/kotlin/g3601_3700/s3618_split_array_by_prime_indices/readme.md b/src/main/kotlin/g3601_3700/s3618_split_array_by_prime_indices/readme.md new file mode 100644 index 00000000..e5c8cfdc --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3618_split_array_by_prime_indices/readme.md @@ -0,0 +1,45 @@ +3618\. Split Array by Prime Indices + +Medium + +You are given an integer array `nums`. + +Split `nums` into two arrays `A` and `B` using the following rule: + +* Elements at **prime** indices in `nums` must go into array `A`. +* All other elements must go into array `B`. + +Return the **absolute** difference between the sums of the two arrays: `|sum(A) - sum(B)|`. + +**Note:** An empty array has a sum of 0. + +**Example 1:** + +**Input:** nums = [2,3,4] + +**Output:** 1 + +**Explanation:** + +* The only prime index in the array is 2, so `nums[2] = 4` is placed in array `A`. +* The remaining elements, `nums[0] = 2` and `nums[1] = 3` are placed in array `B`. +* `sum(A) = 4`, `sum(B) = 2 + 3 = 5`. +* The absolute difference is `|4 - 5| = 1`. + +**Example 2:** + +**Input:** nums = [-1,5,7,0] + +**Output:** 3 + +**Explanation:** + +* The prime indices in the array are 2 and 3, so `nums[2] = 7` and `nums[3] = 0` are placed in array `A`. +* The remaining elements, `nums[0] = -1` and `nums[1] = 5` are placed in array `B`. +* `sum(A) = 7 + 0 = 7`, `sum(B) = -1 + 5 = 4`. +* The absolute difference is `|7 - 4| = 3`. + +**Constraints:** + +* 1 <= nums.length <= 105 +* -109 <= nums[i] <= 109 \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/Solution.kt b/src/main/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/Solution.kt new file mode 100644 index 00000000..e2eac401 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/Solution.kt @@ -0,0 +1,51 @@ +package g3601_3700.s3619_count_islands_with_total_value_divisible_by_k + +// #Medium #Array #Depth_First_Search #Breadth_First_Search #Matrix #Union_Find +// #Biweekly_Contest_161 #2025_07_22_Time_14_ms_(100.00%)_Space_86.20_MB_(47.83%) + +class Solution { + private var m = 0 + private var n = 0 + + fun countIslands(grid: Array, k: Int): Int { + var count = 0 + m = grid.size + n = grid[0].size + for (i in 0..): Int { + if (i >= m || j >= n || i < 0 || j < 0 || grid[i][j] == 0) { + return Int.Companion.MAX_VALUE + } + var count = grid[i][j] + grid[i][j] = 0 + val x = dfs(i + 1, j, grid) + val y = dfs(i, j + 1, grid) + val a = dfs(i - 1, j, grid) + val b = dfs(i, j - 1, grid) + if (x != Int.Companion.MAX_VALUE) { + count += x + } + if (y != Int.Companion.MAX_VALUE) { + count += y + } + if (a != Int.Companion.MAX_VALUE) { + count += a + } + if (b != Int.Companion.MAX_VALUE) { + count += b + } + return count + } +} diff --git a/src/main/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/readme.md b/src/main/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/readme.md new file mode 100644 index 00000000..841a4bc2 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/readme.md @@ -0,0 +1,42 @@ +3619\. Count Islands With Total Value Divisible by K + +Medium + +You are given an `m x n` matrix `grid` and a positive integer `k`. An **island** is a group of **positive** integers (representing land) that are **4-directionally** connected (horizontally or vertically). + +The **total value** of an island is the sum of the values of all cells in the island. + +Return the number of islands with a total value **divisible by** `k`. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2025/03/06/example1griddrawio-1.png) + +**Input:** grid = [[0,2,1,0,0],[0,5,0,0,5],[0,0,1,0,0],[0,1,4,7,0],[0,2,0,0,8]], k = 5 + +**Output:** 2 + +**Explanation:** + +The grid contains four islands. The islands highlighted in blue have a total value that is divisible by 5, while the islands highlighted in red do not. + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2025/03/06/example2griddrawio.png) + +**Input:** grid = [[3,0,3,0], [0,3,0,3], [3,0,3,0]], k = 3 + +**Output:** 6 + +**Explanation:** + +The grid contains six islands, each with a total value that is divisible by 3. + +**Constraints:** + +* `m == grid.length` +* `n == grid[i].length` +* `1 <= m, n <= 1000` +* 1 <= m * n <= 105 +* 0 <= grid[i][j] <= 106 +* 1 <= k <= 106 \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3620_network_recovery_pathways/Solution.kt b/src/main/kotlin/g3601_3700/s3620_network_recovery_pathways/Solution.kt new file mode 100644 index 00000000..993a883f --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3620_network_recovery_pathways/Solution.kt @@ -0,0 +1,97 @@ +package g3601_3700.s3620_network_recovery_pathways + +// #Hard #Array #Dynamic_Programming #Binary_Search #Heap_Priority_Queue #Graph #Topological_Sort +// #Shortest_Path #Biweekly_Contest_161 #2025_07_22_Time_212_ms_(66.67%)_Space_150.09_MB_(13.33%) + +import java.util.LinkedList +import java.util.Queue +import kotlin.math.max + +class Solution { + private fun topologicalSort(n: Int, g: Array>): List { + val indeg = IntArray(n) + for (i in 0 until n) { + for (adjNode in g[i]) { + indeg[adjNode]++ + } + } + val q: Queue = LinkedList() + val ts = ArrayList() + for (i in 0 until n) { + if (indeg[i] == 0) { + q.offer(i) + } + } + while (!q.isEmpty()) { + val u = q.poll() + ts.add(u) + for (v in g[u]) { + indeg[v]-- + if (indeg[v] == 0) { + q.offer(v) + } + } + } + return ts + } + + private fun check( + x: Int, + n: Int, + adj: Array>, + ts: List, + online: BooleanArray, + k: Long, + ): Boolean { + val d = LongArray(n) + d.fill(Long.MAX_VALUE) + d[0] = 0 + for (u in ts) { + if (d[u] != Long.MAX_VALUE) { + for (p in adj[u]) { + val v = p[0] + val c = p[1] + if (c < x || !online[v]) { + continue + } + if (d[u] + c < d[v]) { + d[v] = d[u] + c + } + } + } + } + return d[n - 1] <= k + } + + fun findMaxPathScore(edges: Array, online: BooleanArray, k: Long): Int { + val n = online.size + // Adjacency list for graph with edge weights + val adj = Array>(n) { ArrayList() } + val g = Array>(n) { ArrayList() } + for (e in edges) { + val u = e[0] + val v = e[1] + val c = e[2] + adj[u].add(intArrayOf(v, c)) + g[u].add(v) + } + val ts = topologicalSort(n, g) + if (!check(0, n, adj, ts, online, k)) { + return -1 + } + var l = 0 + var h = 0 + for (e in edges) { + h = max(h, e[2]) + } + while (l < h) { + val md = l + (h - l + 1) / 2 + if (check(md, n, adj, ts, online, k)) { + l = md + } else { + h = md - 1 + } + } + return l + } +} diff --git a/src/main/kotlin/g3601_3700/s3620_network_recovery_pathways/readme.md b/src/main/kotlin/g3601_3700/s3620_network_recovery_pathways/readme.md new file mode 100644 index 00000000..d8aab05a --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3620_network_recovery_pathways/readme.md @@ -0,0 +1,87 @@ +3620\. Network Recovery Pathways + +Hard + +You are given a directed acyclic graph of `n` nodes numbered from 0 to `n − 1`. This is represented by a 2D array `edges` of length `m`, where edges[i] = [ui, vi, costi] indicates a one‑way communication from node ui to node vi with a recovery cost of costi. + +Some nodes may be offline. You are given a boolean array `online` where `online[i] = true` means node `i` is online. Nodes 0 and `n − 1` are always online. + +A path from 0 to `n − 1` is **valid** if: + +* All intermediate nodes on the path are online. +* The total recovery cost of all edges on the path does not exceed `k`. + +For each valid path, define its **score** as the minimum edge‑cost along that path. + +Return the **maximum** path score (i.e., the largest **minimum**\-edge cost) among all valid paths. If no valid path exists, return -1. + +**Example 1:** + +**Input:** edges = [[0,1,5],[1,3,10],[0,2,3],[2,3,4]], online = [true,true,true,true], k = 10 + +**Output:** 3 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/06/06/graph-10.png) + +* The graph has two possible routes from node 0 to node 3: + + 1. Path `0 → 1 → 3` + + * Total cost = `5 + 10 = 15`, which exceeds k (`15 > 10`), so this path is invalid. + + 2. Path `0 → 2 → 3` + + * Total cost = `3 + 4 = 7 <= k`, so this path is valid. + + * The minimum edge‐cost along this path is `min(3, 4) = 3`. + +* There are no other valid paths. Hence, the maximum among all valid path‐scores is 3. + + +**Example 2:** + +**Input:** edges = [[0,1,7],[1,4,5],[0,2,6],[2,3,6],[3,4,2],[2,4,6]], online = [true,true,true,false,true], k = 12 + +**Output:** 6 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/06/06/graph-11.png) + +* Node 3 is offline, so any path passing through 3 is invalid. + +* Consider the remaining routes from 0 to 4: + + 1. Path `0 → 1 → 4` + + * Total cost = `7 + 5 = 12 <= k`, so this path is valid. + + * The minimum edge‐cost along this path is `min(7, 5) = 5`. + + 2. Path `0 → 2 → 3 → 4` + + * Node 3 is offline, so this path is invalid regardless of cost. + + 3. Path `0 → 2 → 4` + + * Total cost = `6 + 6 = 12 <= k`, so this path is valid. + + * The minimum edge‐cost along this path is `min(6, 6) = 6`. + +* Among the two valid paths, their scores are 5 and 6. Therefore, the answer is 6. + + +**Constraints:** + +* `n == online.length` +* 2 <= n <= 5 * 104 +* `0 <= m == edges.length <=` min(105, n * (n - 1) / 2) +* edges[i] = [ui, vi, costi] +* 0 <= ui, vi < n +* ui != vi +* 0 <= costi <= 109 +* 0 <= k <= 5 * 1013 +* `online[i]` is either `true` or `false`, and both `online[0]` and `online[n − 1]` are `true`. +* The given graph is a directed acyclic graph. \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/Solution.kt b/src/main/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/Solution.kt new file mode 100644 index 00000000..69565894 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/Solution.kt @@ -0,0 +1,57 @@ +package g3601_3700.s3621_number_of_integers_with_popcount_depth_equal_to_k_i + +// #Hard #Dynamic_Programming #Math #Combinatorics #Biweekly_Contest_161 +// #2025_07_22_Time_2_ms_(100.00%)_Space_41.19_MB_(100.00%) + +class Solution { + companion object { + private val comb = Array(61) { LongArray(61) } + private val depth = IntArray(61) + + init { + for (i in 0..60) { + comb[i][0] = 1L + comb[i][i] = 1L + for (j in 1 until i) { + comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j] + } + } + depth[1] = 0 + for (i in 2..60) { + depth[i] = depth[i.countOneBits()] + 1 + } + } + } + + fun popcountDepth(n: Long, k: Int): Long { + if (k == 0) { return 1L } + fun countPop(x: Long, c: Int): Long { + var res = 0L + var ones = 0 + var bits = 0 + var t = x + while (t > 0) { + bits++ + t = t shr 1 + } + for (i in bits - 1 downTo 0) { + if ((x shr i) and 1L == 1L) { + val rem = c - ones + if (rem in 0..i) { + res += comb[i][rem] + } + ones++ + } + } + return if (ones == c) res + 1 else res + } + var ans = 0L + for (c in 1..60) { + if (depth[c] == k - 1) { + ans += countPop(n, c) + } + } + if (k == 1) { ans-- } + return ans + } +} diff --git a/src/main/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/readme.md b/src/main/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/readme.md new file mode 100644 index 00000000..bc2f988a --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/readme.md @@ -0,0 +1,60 @@ +3621\. Number of Integers With Popcount-Depth Equal to K I + +Hard + +You are given two integers `n` and `k`. + +For any positive integer `x`, define the following sequence: + +* p0 = x +* pi+1 = popcount(pi) for all `i >= 0`, where `popcount(y)` is the number of set bits (1's) in the binary representation of `y`. + +This sequence will eventually reach the value 1. + +The **popcount-depth** of `x` is defined as the **smallest** integer `d >= 0` such that pd = 1. + +For example, if `x = 7` (binary representation `"111"`). Then, the sequence is: `7 → 3 → 2 → 1`, so the popcount-depth of 7 is 3. + +Your task is to determine the number of integers in the range `[1, n]` whose popcount-depth is **exactly** equal to `k`. + +Return the number of such integers. + +**Example 1:** + +**Input:** n = 4, k = 1 + +**Output:** 2 + +**Explanation:** + +The following integers in the range `[1, 4]` have popcount-depth exactly equal to 1: + +| x | Binary | Sequence | +|---|--------|------------| +| 2 | `"10"` | `2 → 1` | +| 4 | `"100"`| `4 → 1` | + +Thus, the answer is 2. + +**Example 2:** + +**Input:** n = 7, k = 2 + +**Output:** 3 + +**Explanation:** + +The following integers in the range `[1, 7]` have popcount-depth exactly equal to 2: + +| x | Binary | Sequence | +|---|---------|----------------| +| 3 | `"11"` | `3 → 2 → 1` | +| 5 | `"101"` | `5 → 2 → 1` | +| 6 | `"110"` | `6 → 2 → 1` | + +Thus, the answer is 3. + +**Constraints:** + +* 1 <= n <= 1015 +* `0 <= k <= 5` \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/Solution.kt b/src/main/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/Solution.kt new file mode 100644 index 00000000..1be2737e --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/Solution.kt @@ -0,0 +1,17 @@ +package g3601_3700.s3622_check_divisibility_by_digit_sum_and_product + +// #Easy #Math #Weekly_Contest_459 #2025_07_22_Time_0_ms_(100.00%)_Space_40.35_MB_(100.00%) + +class Solution { + fun checkDivisibility(n: Int): Boolean { + var x = n + var sum = 0 + var mul = 1 + while (x != 0) { + sum += x % 10 + mul *= x % 10 + x = x / 10 + } + return n % (sum + mul) == 0 + } +} diff --git a/src/main/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/readme.md b/src/main/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/readme.md new file mode 100644 index 00000000..c033e3f1 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/readme.md @@ -0,0 +1,36 @@ +3622\. Check Divisibility by Digit Sum and Product + +Easy + +You are given a positive integer `n`. Determine whether `n` is divisible by the **sum** of the following two values: + +* The **digit sum** of `n` (the sum of its digits). + +* The **digit** **product** of `n` (the product of its digits). + + +Return `true` if `n` is divisible by this sum; otherwise, return `false`. + +**Example 1:** + +**Input:** n = 99 + +**Output:** true + +**Explanation:** + +Since 99 is divisible by the sum (9 + 9 = 18) plus product (9 \* 9 = 81) of its digits (total 99), the output is true. + +**Example 2:** + +**Input:** n = 23 + +**Output:** false + +**Explanation:** + +Since 23 is not divisible by the sum (2 + 3 = 5) plus product (2 \* 3 = 6) of its digits (total 11), the output is false. + +**Constraints:** + +* 1 <= n <= 106 \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/Solution.kt b/src/main/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/Solution.kt new file mode 100644 index 00000000..b9e9d81e --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/Solution.kt @@ -0,0 +1,27 @@ +package g3601_3700.s3623_count_number_of_trapezoids_i + +// #Medium #Array #Hash_Table #Math #Geometry #Weekly_Contest_459 +// #2025_07_22_Time_58_ms_(68.00%)_Space_139.38_MB_(8.00%) + +class Solution { + fun countTrapezoids(points: Array): Int { + val mod = 1000000007 + val inv = 500000004L + val map: MutableMap = HashMap(points.size) + for (p in points) { + map.merge(p[1], 1) { a: Int, b: Int -> Integer.sum(a, b) } + } + var sum = 0L + var sumPairs = 0L + for (num in map.values) { + if (num > 1) { + val pairs = (num.toLong() * (num - 1) / 2) % mod + sum = (sum + pairs) % mod + sumPairs = (sumPairs + pairs * pairs % mod) % mod + } + } + var res = (sum * sum % mod - sumPairs + mod) % mod + res = (res * inv) % mod + return res.toInt() + } +} diff --git a/src/main/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/readme.md b/src/main/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/readme.md new file mode 100644 index 00000000..2debd6da --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/readme.md @@ -0,0 +1,45 @@ +3623\. Count Number of Trapezoids I + +Medium + +You are given a 2D integer array `points`, where points[i] = [xi, yi] represents the coordinates of the ith point on the Cartesian plane. + +A **horizontal** **trapezoid** is a convex quadrilateral with **at least one pair** of horizontal sides (i.e. parallel to the x-axis). Two lines are parallel if and only if they have the same slope. + +Return the _number of unique_ **_horizontal_ _trapezoids_** that can be formed by choosing any four distinct points from `points`. + +Since the answer may be very large, return it **modulo** 109 + 7. + +**Example 1:** + +**Input:** points = [[1,0],[2,0],[3,0],[2,2],[3,2]] + +**Output:** 3 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/05/01/desmos-graph-6.png) ![](https://assets.leetcode.com/uploads/2025/05/01/desmos-graph-7.png) ![](https://assets.leetcode.com/uploads/2025/05/01/desmos-graph-8.png) + +There are three distinct ways to pick four points that form a horizontal trapezoid: + +* Using points `[1,0]`, `[2,0]`, `[3,2]`, and `[2,2]`. +* Using points `[2,0]`, `[3,0]`, `[3,2]`, and `[2,2]`. +* Using points `[1,0]`, `[3,0]`, `[3,2]`, and `[2,2]`. + +**Example 2:** + +**Input:** points = [[0,0],[1,0],[0,1],[2,1]] + +**Output:** 1 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/04/29/desmos-graph-5.png) + +There is only one horizontal trapezoid that can be formed. + +**Constraints:** + +* 4 <= points.length <= 105 +* –108 <= xi, yi <= 108 +* All points are pairwise distinct. \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/Solution.kt b/src/main/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/Solution.kt new file mode 100644 index 00000000..971f2f1d --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/Solution.kt @@ -0,0 +1,105 @@ +package g3601_3700.s3624_number_of_integers_with_popcount_depth_equal_to_k_ii + +// #Hard #Array #Segment_Tree #Weekly_Contest_459 +// #2025_07_22_Time_38_ms_(100.00%)_Space_134.15_MB_(100.00%) + +class Solution { + private fun computeDepth(number: Long): Int { + if (number == 1L) { + return 0 + } + return 1 + DEPTH_TABLE[java.lang.Long.bitCount(number)] + } + + fun popcountDepth(nums: LongArray, queries: Array): IntArray { + val len = nums.size + val maxDepth = 6 + val trees = Array(maxDepth) { FenwickTree() } + for (d in 0..() + for (query in queries) { + val type = query[0].toInt() + if (type == 1) { + val left = query[1].toInt() + val right = query[2].toInt() + val depth = query[3].toInt() + if (depth >= 0 && depth < maxDepth) { + ansList.add(trees[depth].queryRange(left + 1, right + 1)) + } else { + ansList.add(0) + } + } else if (type == 2) { + val index = query[1].toInt() + val newVal = query[2] + val oldDepth = computeDepth(nums[index]) + if (oldDepth < maxDepth) { + trees[oldDepth].update(index + 1, -1) + } + nums[index] = newVal + val newDepth = computeDepth(newVal) + if (newDepth < maxDepth) { + trees[newDepth].update(index + 1, 1) + } + } + } + val ansArray = IntArray(ansList.size) + for (i in ansList.indices) { + ansArray[i] = ansList[i]!! + } + return ansArray + } + + private class FenwickTree { + private lateinit var tree: IntArray + private var size = 0 + + fun build(n: Int) { + this.size = n + this.tree = IntArray(size + 1) + } + + fun update(index: Int, value: Int) { + var index = index + while (index <= size) { + tree[index] += value + index += index and (-index) + } + } + + fun query(index: Int): Int { + var index = index + var result = 0 + while (index > 0) { + result += tree[index] + index -= index and (-index) + } + return result + } + + fun queryRange(left: Int, right: Int): Int { + if (left > right) { + return 0 + } + return query(right) - query(left - 1) + } + } + + companion object { + private val DEPTH_TABLE = IntArray(65) + + init { + DEPTH_TABLE[1] = 0 + for (i in 2..64) { + DEPTH_TABLE[i] = 1 + DEPTH_TABLE[Integer.bitCount(i)] + } + } + } +} diff --git a/src/main/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/readme.md b/src/main/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/readme.md new file mode 100644 index 00000000..50904c08 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/readme.md @@ -0,0 +1,86 @@ +3624\. Number of Integers With Popcount-Depth Equal to K II + +Hard + +You are given an integer array `nums`. + +For any positive integer `x`, define the following sequence: + +* p0 = x +* pi+1 = popcount(pi) for all `i >= 0`, where `popcount(y)` is the number of set bits (1's) in the binary representation of `y`. + +This sequence will eventually reach the value 1. + +The **popcount-depth** of `x` is defined as the **smallest** integer `d >= 0` such that pd = 1. + +For example, if `x = 7` (binary representation `"111"`). Then, the sequence is: `7 → 3 → 2 → 1`, so the popcount-depth of 7 is 3. + +You are also given a 2D integer array `queries`, where each `queries[i]` is either: + +* `[1, l, r, k]` - **Determine** the number of indices `j` such that `l <= j <= r` and the **popcount-depth** of `nums[j]` is equal to `k`. +* `[2, idx, val]` - **Update** `nums[idx]` to `val`. + +Return an integer array `answer`, where `answer[i]` is the number of indices for the ith query of type `[1, l, r, k]`. + +**Example 1:** + +**Input:** nums = [2,4], queries = [[1,0,1,1],[2,1,1],[1,0,1,0]] + +**Output:** [2,1] + +**Explanation:** + +| `i` | `queries[i]` | `nums` | binary(`nums`) | popcount-
depth | `[l, r]` | `k` | Valid
`nums[j]` | updated
`nums` | Answer | +|-----|--------------|----------|----------------|---------------------|----------|-----|---------------------|--------------------|---------| +| 0 | [1,0,1,1] | [2,4] | [10, 100] | [1, 1] | [0, 1] | 1 | [0, 1] | — | 2 | +| 1 | [2,1,1] | [2,4] | [10, 100] | [1, 1] | — | — | — | [2,1] | — | +| 2 | [1,0,1,0] | [2,1] | [10, 1] | [1, 0] | [0, 1] | 0 | [1] | — | 1 | + +Thus, the final `answer` is `[2, 1]`. + +**Example 2:** + +**Input:** nums = [3,5,6], queries = [[1,0,2,2],[2,1,4],[1,1,2,1],[1,0,1,0]] + +**Output:** [3,1,0] + +**Explanation:** + +| `i` | `queries[i]` | `nums` | binary(`nums`) | popcount-
depth | `[l, r]` | `k` | Valid
`nums[j]` | updated
`nums` | Answer | +|-----|----------------|----------------|-----------------------|---------------------|----------|-----|---------------------|--------------------|---------| +| 0 | [1,0,2,2] | [3, 5, 6] | [11, 101, 110] | [2, 2, 2] | [0, 2] | 2 | [0, 1, 2] | — | 3 | +| 1 | [2,1,4] | [3, 5, 6] | [11, 101, 110] | [2, 2, 2] | — | — | — | [3, 4, 6] | — | +| 2 | [1,1,2,1] | [3, 4, 6] | [11, 100, 110] | [2, 1, 2] | [1, 2] | 1 | [1] | — | 1 | +| 3 | [1,0,1,0] | [3, 4, 6] | [11, 100, 110] | [2, 1, 2] | [0, 1] | 0 | [] | — | 0 | + +Thus, the final `answer` is `[3, 1, 0]`. + +**Example 3:** + +**Input:** nums = [1,2], queries = [[1,0,1,1],[2,0,3],[1,0,0,1],[1,0,0,2]] + +**Output:** [1,0,1] + +**Explanation:** + +| `i` | `queries[i]` | `nums` | binary(`nums`) | popcount-
depth | `[l, r]` | `k` | Valid
`nums[j]` | updated
`nums` | Answer | +|-----|----------------|------------|----------------|---------------------|----------|-----|--------------------|--------------------|---------| +| 0 | [1,0,1,1] | [1, 2] | [1, 10] | [0, 1] | [0, 1] | 1 | [1] | — | 1 | +| 1 | [2,0,3] | [1, 2] | [1, 10] | [0, 1] | — | — | — | [3, 2] | | +| 2 | [1,0,0,1] | [3, 2] | [11, 10] | [2, 1] | [0, 0] | 1 | [] | — | 0 | +| 3 | [1,0,0,2] | [3, 2] | [11, 10] | [2, 1] | [0, 0] | 2 | [0] | — | 1 | + +Thus, the final `answer` is `[1, 0, 1]`. + +**Constraints:** + +* 1 <= n == nums.length <= 105 +* 1 <= nums[i] <= 1015 +* 1 <= queries.length <= 105 +* `queries[i].length == 3` or `4` + * `queries[i] == [1, l, r, k]` or, + * `queries[i] == [2, idx, val]` + * `0 <= l <= r <= n - 1` + * `0 <= k <= 5` + * `0 <= idx <= n - 1` + * 1 <= val <= 1015 \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/Solution.kt b/src/main/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/Solution.kt new file mode 100644 index 00000000..abdec712 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/Solution.kt @@ -0,0 +1,117 @@ +package g3601_3700.s3625_count_number_of_trapezoids_ii + +// #Hard #Array #Hash_Table #Math #Geometry #Weekly_Contest_459 +// #2025_07_22_Time_377_ms_(100.00%)_Space_162.04_MB_(37.50%) + +import kotlin.math.abs + +class Solution { + private class Slope(var dx: Int, var dy: Int) { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + if (other !is Slope) { + return false + } + val s: Slope = other + return dx == s.dx && dy == s.dy + } + + override fun hashCode(): Int { + return dx * 1000003 xor dy + } + } + + private class Pair(var a: Int, var b: Int) { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + if (other !is Pair) { + return false + } + val p = other + return a == p.a && b == p.b + } + + override fun hashCode(): Int { + return a * 1000003 xor b + } + } + + fun countTrapezoids(points: Array): Int { + val n = points.size + val slopeLines: MutableMap> = HashMap() + val midpointSlopes: MutableMap> = HashMap>() + for (i in 0.. HashMap() } + .merge(lineId, 1) { a: Int, b: Int -> Integer.sum(a, b) } + val mx = x1 + x2 + val my = y1 + y2 + val mid = Pair(mx, my) + midpointSlopes + .computeIfAbsent(mid) { _: Pair -> HashMap() } + .merge(slopeKey, 1) { a: Int, b: Int -> Integer.sum(a, b) } + } + } + var trapezoidsRaw: Long = 0 + for (lines in slopeLines.values) { + if (lines.size < 2) { + continue + } + var s: Long = 0 + var s2: Long = 0 + for (line in lines.values) { + s += line.toLong() + s2 += line.toLong() * line + } + trapezoidsRaw += (s * s - s2) / 2 + } + var parallelograms: Long = 0 + for (mp in midpointSlopes.values) { + if (mp.size < 2) { + continue + } + var s: Long = 0 + var s2: Long = 0 + for (num in mp.values) { + s += num.toLong() + s2 += num.toLong() * num + } + parallelograms += (s * s - s2) / 2 + } + val res = trapezoidsRaw - parallelograms + return if (res > Int.Companion.MAX_VALUE) Int.Companion.MAX_VALUE else res.toInt() + } + + private fun gcd(a: Int, b: Int): Int { + var a = a + var b = b + while (b != 0) { + val t = a % b + a = b + b = t + } + return if (a == 0) 1 else a + } +} diff --git a/src/main/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/readme.md b/src/main/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/readme.md new file mode 100644 index 00000000..bda582e7 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/readme.md @@ -0,0 +1,42 @@ +3625\. Count Number of Trapezoids II + +Hard + +You are given a 2D integer array `points` where points[i] = [xi, yi] represents the coordinates of the ith point on the Cartesian plane. + +Return _the number of unique_ _trapezoids_ that can be formed by choosing any four distinct points from `points`. + +A **trapezoid** is a convex quadrilateral with **at least one pair** of parallel sides. Two lines are parallel if and only if they have the same slope. + +**Example 1:** + +**Input:** points = [[-3,2],[3,0],[2,3],[3,2],[2,-3]] + +**Output:** 2 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/04/29/desmos-graph-4.png) ![](https://assets.leetcode.com/uploads/2025/04/29/desmos-graph-3.png) + +There are two distinct ways to pick four points that form a trapezoid: + +* The points `[-3,2], [2,3], [3,2], [2,-3]` form one trapezoid. +* The points `[2,3], [3,2], [3,0], [2,-3]` form another trapezoid. + +**Example 2:** + +**Input:** points = [[0,0],[1,0],[0,1],[2,1]] + +**Output:** 1 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/04/29/desmos-graph-5.png) + +There is only one trapezoid which can be formed. + +**Constraints:** + +* `4 <= points.length <= 500` +* –1000 <= xi, yi <= 1000 +* All points are pairwise distinct. \ No newline at end of file diff --git a/src/test/kotlin/g3601_3700/s3618_split_array_by_prime_indices/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3618_split_array_by_prime_indices/SolutionTest.kt new file mode 100644 index 00000000..3ec1a367 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3618_split_array_by_prime_indices/SolutionTest.kt @@ -0,0 +1,39 @@ +package g3601_3700.s3618_split_array_by_prime_indices + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun splitArray() { + assertThat(Solution().splitArray(intArrayOf(2, 3, 4)), equalTo(1L)) + } + + @Test + fun splitArray2() { + assertThat(Solution().splitArray(intArrayOf(-1, 5, 7, 0)), equalTo(3L)) + } + + @Test + fun splitArray3() { + assertThat( + Solution() + .splitArray( + intArrayOf( + -54818575, + 801071518, + 745054848, + -415289833, + 161564441, + 706292027, + 306478283, + 943480367, + 222076810, + 992619933, + ), + ), + equalTo(449455001L), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/SolutionTest.kt new file mode 100644 index 00000000..1063b039 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3619_count_islands_with_total_value_divisible_by_k/SolutionTest.kt @@ -0,0 +1,41 @@ +package g3601_3700.s3619_count_islands_with_total_value_divisible_by_k + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun countIslands() { + assertThat( + Solution() + .countIslands( + arrayOf( + intArrayOf(0, 2, 1, 0, 0), + intArrayOf(0, 5, 0, 0, 5), + intArrayOf(0, 0, 1, 0, 0), + intArrayOf(0, 1, 4, 7, 0), + intArrayOf(0, 2, 0, 0, 8), + ), + 5, + ), + equalTo(2), + ) + } + + @Test + fun countIslands2() { + assertThat( + Solution() + .countIslands( + arrayOf( + intArrayOf(3, 0, 3, 0), + intArrayOf(0, 3, 0, 3), + intArrayOf(3, 0, 3, 0), + ), + 3, + ), + equalTo(6), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3620_network_recovery_pathways/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3620_network_recovery_pathways/SolutionTest.kt new file mode 100644 index 00000000..261f6d4f --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3620_network_recovery_pathways/SolutionTest.kt @@ -0,0 +1,45 @@ +package g3601_3700.s3620_network_recovery_pathways + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun findMaxPathScore() { + assertThat( + Solution() + .findMaxPathScore( + arrayOf( + intArrayOf(0, 1, 5), + intArrayOf(1, 3, 10), + intArrayOf(0, 2, 3), + intArrayOf(2, 3, 4), + ), + booleanArrayOf(true, true, true, true), + 10L, + ), + equalTo(3), + ) + } + + @Test + fun findMaxPathScore2() { + assertThat( + Solution() + .findMaxPathScore( + arrayOf( + intArrayOf(0, 1, 7), + intArrayOf(1, 4, 5), + intArrayOf(0, 2, 6), + intArrayOf(2, 3, 6), + intArrayOf(3, 4, 2), + intArrayOf(2, 4, 6), + ), + booleanArrayOf(true, true, true, false, true), + 12L, + ), + equalTo(6), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/SolutionTest.kt new file mode 100644 index 00000000..ef492d0b --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3621_number_of_integers_with_popcount_depth_equal_to_k_i/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3601_3700.s3621_number_of_integers_with_popcount_depth_equal_to_k_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun popcountDepth() { + assertThat(Solution().popcountDepth(4L, 1), equalTo(2L)) + } + + @Test + fun popcountDepth2() { + assertThat(Solution().popcountDepth(7L, 2), equalTo(3L)) + } +} diff --git a/src/test/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/SolutionTest.kt new file mode 100644 index 00000000..5623e091 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3622_check_divisibility_by_digit_sum_and_product/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3601_3700.s3622_check_divisibility_by_digit_sum_and_product + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun checkDivisibility() { + assertThat(Solution().checkDivisibility(99), equalTo(true)) + } + + @Test + fun checkDivisibility2() { + assertThat(Solution().checkDivisibility(23), equalTo(false)) + } +} diff --git a/src/test/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/SolutionTest.kt new file mode 100644 index 00000000..0108b0df --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3623_count_number_of_trapezoids_i/SolutionTest.kt @@ -0,0 +1,39 @@ +package g3601_3700.s3623_count_number_of_trapezoids_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun countTrapezoids() { + assertThat( + Solution() + .countTrapezoids( + arrayOf( + intArrayOf(1, 0), + intArrayOf(2, 0), + intArrayOf(3, 0), + intArrayOf(2, 2), + intArrayOf(3, 2), + ), + ), + equalTo(3), + ) + } + + @Test + fun countTrapezoids2() { + assertThat( + Solution().countTrapezoids( + arrayOf( + intArrayOf(0, 0), + intArrayOf(1, 0), + intArrayOf(0, 1), + intArrayOf(2, 1), + ), + ), + equalTo(1), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/SolutionTest.kt new file mode 100644 index 00000000..c93059a3 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3624_number_of_integers_with_popcount_depth_equal_to_k_ii/SolutionTest.kt @@ -0,0 +1,53 @@ +package g3601_3700.s3624_number_of_integers_with_popcount_depth_equal_to_k_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun popcountDepth() { + assertThat( + Solution() + .popcountDepth( + longArrayOf(2, 4), + arrayOf(longArrayOf(1, 0, 1, 1), longArrayOf(2, 1, 1), longArrayOf(1, 0, 1, 0)), + ), + equalTo(intArrayOf(2, 1)), + ) + } + + @Test + fun popcountDepth2() { + assertThat( + Solution() + .popcountDepth( + longArrayOf(3, 5, 6), + arrayOf( + longArrayOf(1, 0, 2, 2), + longArrayOf(2, 1, 4), + longArrayOf(1, 1, 2, 1), + longArrayOf(1, 0, 1, 0), + ), + ), + equalTo(intArrayOf(3, 1, 0)), + ) + } + + @Test + fun popcountDepth3() { + assertThat( + Solution() + .popcountDepth( + longArrayOf(1, 2), + arrayOf( + longArrayOf(1, 0, 1, 1), + longArrayOf(2, 0, 3), + longArrayOf(1, 0, 0, 1), + longArrayOf(1, 0, 0, 2), + ), + ), + equalTo(intArrayOf(1, 0, 1)), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/SolutionTest.kt new file mode 100644 index 00000000..13c28de9 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3625_count_number_of_trapezoids_ii/SolutionTest.kt @@ -0,0 +1,58 @@ +package g3601_3700.s3625_count_number_of_trapezoids_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun countTrapezoids() { + assertThat( + Solution() + .countTrapezoids( + arrayOf( + intArrayOf(-3, 2), + intArrayOf(3, 0), + intArrayOf(2, 3), + intArrayOf(3, 2), + intArrayOf(2, -3), + ), + ), + equalTo(2), + ) + } + + @Test + fun countTrapezoids2() { + assertThat( + Solution().countTrapezoids( + arrayOf( + intArrayOf(0, 0), + intArrayOf(1, 0), + intArrayOf(0, 1), + intArrayOf(2, 1), + ), + ), + equalTo(1), + ) + } + + @Test + fun countTrapezoids3() { + assertThat( + Solution() + .countTrapezoids( + arrayOf( + intArrayOf(71, -89), + intArrayOf(-75, -89), + intArrayOf(-9, 11), + intArrayOf(-24, -89), + intArrayOf(-51, -89), + intArrayOf(-77, -89), + intArrayOf(42, 11), + ), + ), + equalTo(10), + ) + } +}