diff --git a/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README.md b/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README.md index fa1d6026b421f..79cf04675bf8b 100644 --- a/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README.md +++ b/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README.md @@ -103,7 +103,15 @@ tags: -### 方法一 +### 方法一:前缀和 + +根据题目描述,我们不妨假设把一个元素 $x$ 变为 $0$ 需要的最小操作次数为 $p$,那么 $p$ 是满足 $4^p \gt x$ 的最小整数。 + +我们知道了一个元素的最小操作次数,那么对于一个范围 $[l, r]$,我们假设 $[l, r]$ 范围内所有元素的**最小操作次数之和**为 $s$,**最大操作次数**为元素 $r$ 的操作次数 $mx$,那么 $[l, r]$ 范围内所有元素变为 $0$ 的最少操作次数为 $\max(\lceil s / 2 \rceil, mx)$。 + +我们定义一个函数 $f(x)$,表示范围 $[1, x]$ 内所有元素的最小操作次数之和,那么对于每个查询 $[l, r]$,我们可以计算出 $s = f(r) - f(l - 1)$ 和 $mx = f(r) - f(r - 1)$,从而得到答案。 + +时间复杂度 $O(q \log M)$,其中 $q$ 是查询次数,而 $M$ 是查询范围的最大值。空间复杂度 $O(1)$。 @@ -243,6 +251,37 @@ function minOperations(queries: number[][]): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn min_operations(queries: Vec>) -> i64 { + let f = |x: i64| -> i64 { + let mut res: i64 = 0; + let mut p: i64 = 1; + let mut i: i64 = 1; + while p <= x { + let cnt = std::cmp::min(p * 4 - 1, x) - p + 1; + res += cnt * i; + i += 1; + p *= 4; + } + res + }; + + let mut ans: i64 = 0; + for q in queries { + let l = q[0] as i64; + let r = q[1] as i64; + let s = f(r) - f(l - 1); + let mx = f(r) - f(r - 1); + ans += std::cmp::max((s + 1) / 2, mx); + } + ans + } +} +``` + diff --git a/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README_EN.md b/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README_EN.md index df1daa376a745..2de28ae5bd217 100644 --- a/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README_EN.md +++ b/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README_EN.md @@ -100,7 +100,15 @@ tags: -### Solution 1 +### Solution 1: Prefix Sum + +According to the problem description, suppose the minimum number of operations required to make an element $x$ become $0$ is $p$, where $p$ is the smallest integer such that $4^p > x$. + +Once we know the minimum number of operations for each element, for a range $[l, r]$, let $s$ be the sum of the minimum operations for all elements in $[l, r]$, and let $mx$ be the maximum number of operations, which is the number of operations for element $r$. Then, the minimum number of operations to make all elements in $[l, r]$ become $0$ is $\max(\lceil s / 2 \rceil, mx)$. + +We define a function $f(x)$ to represent the sum of the minimum operations for all elements in the range $[1, x]$. For each query $[l, r]$, we can compute $s = f(r) - f(l - 1)$ and $mx = f(r) - f(r - 1)$ to obtain the answer. + +The time complexity is $O(q \log M)$, where $q$ is the number of queries and $M$ is the maximum value in the query range. The space complexity is $O(1)$. @@ -240,6 +248,37 @@ function minOperations(queries: number[][]): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn min_operations(queries: Vec>) -> i64 { + let f = |x: i64| -> i64 { + let mut res: i64 = 0; + let mut p: i64 = 1; + let mut i: i64 = 1; + while p <= x { + let cnt = std::cmp::min(p * 4 - 1, x) - p + 1; + res += cnt * i; + i += 1; + p *= 4; + } + res + }; + + let mut ans: i64 = 0; + for q in queries { + let l = q[0] as i64; + let r = q[1] as i64; + let s = f(r) - f(l - 1); + let mx = f(r) - f(r - 1); + ans += std::cmp::max((s + 1) / 2, mx); + } + ans + } +} +``` + diff --git a/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/Solution.rs b/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/Solution.rs new file mode 100644 index 0000000000000..25c8556a51410 --- /dev/null +++ b/solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/Solution.rs @@ -0,0 +1,26 @@ +impl Solution { + pub fn min_operations(queries: Vec>) -> i64 { + let f = |x: i64| -> i64 { + let mut res: i64 = 0; + let mut p: i64 = 1; + let mut i: i64 = 1; + while p <= x { + let cnt = std::cmp::min(p * 4 - 1, x) - p + 1; + res += cnt * i; + i += 1; + p *= 4; + } + res + }; + + let mut ans: i64 = 0; + for q in queries { + let l = q[0] as i64; + let r = q[1] as i64; + let s = f(r) - f(l - 1); + let mx = f(r) - f(r - 1); + ans += std::cmp::max((s + 1) / 2, mx); + } + ans + } +}