Skip to content

Commit ac0cf6e

Browse files
authored
feat: add solutions to lc problem: No.3495 (#4697)
1 parent 4410451 commit ac0cf6e

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README.md

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,15 @@ tags:
103103

104104
<!-- solution:start -->
105105

106-
### 方法一
106+
### 方法一:前缀和
107+
108+
根据题目描述,我们不妨假设把一个元素 $x$ 变为 $0$ 需要的最小操作次数为 $p$,那么 $p$ 是满足 $4^p \gt x$ 的最小整数。
109+
110+
我们知道了一个元素的最小操作次数,那么对于一个范围 $[l, r]$,我们假设 $[l, r]$ 范围内所有元素的**最小操作次数之和**为 $s$,**最大操作次数**为元素 $r$ 的操作次数 $mx$,那么 $[l, r]$ 范围内所有元素变为 $0$ 的最少操作次数为 $\max(\lceil s / 2 \rceil, mx)$。
111+
112+
我们定义一个函数 $f(x)$,表示范围 $[1, x]$ 内所有元素的最小操作次数之和,那么对于每个查询 $[l, r]$,我们可以计算出 $s = f(r) - f(l - 1)$ 和 $mx = f(r) - f(r - 1)$,从而得到答案。
113+
114+
时间复杂度 $O(q \log M)$,其中 $q$ 是查询次数,而 $M$ 是查询范围的最大值。空间复杂度 $O(1)$。
107115

108116
<!-- tabs:start -->
109117

@@ -243,6 +251,37 @@ function minOperations(queries: number[][]): number {
243251
}
244252
```
245253

254+
#### Rust
255+
256+
```rust
257+
impl Solution {
258+
pub fn min_operations(queries: Vec<Vec<i32>>) -> i64 {
259+
let f = |x: i64| -> i64 {
260+
let mut res: i64 = 0;
261+
let mut p: i64 = 1;
262+
let mut i: i64 = 1;
263+
while p <= x {
264+
let cnt = std::cmp::min(p * 4 - 1, x) - p + 1;
265+
res += cnt * i;
266+
i += 1;
267+
p *= 4;
268+
}
269+
res
270+
};
271+
272+
let mut ans: i64 = 0;
273+
for q in queries {
274+
let l = q[0] as i64;
275+
let r = q[1] as i64;
276+
let s = f(r) - f(l - 1);
277+
let mx = f(r) - f(r - 1);
278+
ans += std::cmp::max((s + 1) / 2, mx);
279+
}
280+
ans
281+
}
282+
}
283+
```
284+
246285
<!-- tabs:end -->
247286

248287
<!-- solution:end -->

solution/3400-3499/3495.Minimum Operations to Make Array Elements Zero/README_EN.md

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,15 @@ tags:
100100

101101
<!-- solution:start -->
102102

103-
### Solution 1
103+
### Solution 1: Prefix Sum
104+
105+
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$.
106+
107+
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)$.
108+
109+
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.
110+
111+
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)$.
104112

105113
<!-- tabs:start -->
106114

@@ -240,6 +248,37 @@ function minOperations(queries: number[][]): number {
240248
}
241249
```
242250

251+
#### Rust
252+
253+
```rust
254+
impl Solution {
255+
pub fn min_operations(queries: Vec<Vec<i32>>) -> i64 {
256+
let f = |x: i64| -> i64 {
257+
let mut res: i64 = 0;
258+
let mut p: i64 = 1;
259+
let mut i: i64 = 1;
260+
while p <= x {
261+
let cnt = std::cmp::min(p * 4 - 1, x) - p + 1;
262+
res += cnt * i;
263+
i += 1;
264+
p *= 4;
265+
}
266+
res
267+
};
268+
269+
let mut ans: i64 = 0;
270+
for q in queries {
271+
let l = q[0] as i64;
272+
let r = q[1] as i64;
273+
let s = f(r) - f(l - 1);
274+
let mx = f(r) - f(r - 1);
275+
ans += std::cmp::max((s + 1) / 2, mx);
276+
}
277+
ans
278+
}
279+
}
280+
```
281+
243282
<!-- tabs:end -->
244283

245284
<!-- solution:end -->
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
impl Solution {
2+
pub fn min_operations(queries: Vec<Vec<i32>>) -> i64 {
3+
let f = |x: i64| -> i64 {
4+
let mut res: i64 = 0;
5+
let mut p: i64 = 1;
6+
let mut i: i64 = 1;
7+
while p <= x {
8+
let cnt = std::cmp::min(p * 4 - 1, x) - p + 1;
9+
res += cnt * i;
10+
i += 1;
11+
p *= 4;
12+
}
13+
res
14+
};
15+
16+
let mut ans: i64 = 0;
17+
for q in queries {
18+
let l = q[0] as i64;
19+
let r = q[1] as i64;
20+
let s = f(r) - f(l - 1);
21+
let mx = f(r) - f(r - 1);
22+
ans += std::cmp::max((s + 1) / 2, mx);
23+
}
24+
ans
25+
}
26+
}

0 commit comments

Comments
 (0)