Skip to content

Commit

Permalink
Add problem 2382: Maximum Segment Sum After Removals
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Jan 2, 2025
1 parent 2d8802f commit f770836
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,7 @@ pub mod problem_2375_construct_smallest_number_from_di_string;
pub mod problem_2379_minimum_recolors_to_get_k_consecutive_black_blocks;
pub mod problem_2380_time_needed_to_rearrange_a_binary_string;
pub mod problem_2381_shifting_letters_ii;
pub mod problem_2382_maximum_segment_sum_after_removals;

#[cfg(test)]
mod test_utilities;
35 changes: 35 additions & 0 deletions src/problem_2382_maximum_segment_sum_after_removals/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
pub mod reversed_iteration;

pub trait Solution {
fn maximum_segment_sum(nums: Vec<i32>, remove_queries: Vec<i32>) -> Vec<i64>;
}

#[cfg(test)]
mod tests {
use super::Solution;

pub fn run<S: Solution>() {
let test_cases = [
(
(&[1, 2, 5, 6, 1] as &[_], &[0, 3, 2, 4, 1] as &[_]),
&[14_i64, 7, 2, 2, 0] as &[_],
),
((&[3, 2, 11, 1], &[3, 2, 1, 0]), &[16, 5, 3, 0]),
(
(
&[
244, 19, 445, 671, 801, 103, 291, 335, 781, 33, 51, 789, 746, 510, 38, 7, 529, 905,
],
&[4, 8, 11, 12, 1, 5, 0, 9, 6, 17, 3, 15, 14, 7, 2, 13, 16, 10],
),
&[
5118, 3608, 2735, 1989, 1989, 1989, 1989, 1989, 1989, 1116, 1084, 548, 529, 529, 529, 529, 51, 0,
],
),
];

for ((nums, remove_queries), expected) in test_cases {
assert_eq!(S::maximum_segment_sum(nums.to_vec(), remove_queries.to_vec()), expected);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::cell::Cell;
use std::iter;

struct Item {
end_index: Cell<usize>,
sum: Cell<u64>,
}

impl Solution {
fn filter(item: &Item) -> Option<(&Item, u64)> {
let item_sum = item.sum.get();

(item_sum != 0).then_some((item, item_sum))
}

pub fn maximum_segment_sum(nums: Vec<i32>, remove_queries: Vec<i32>) -> Vec<i64> {
let n = remove_queries.len();

let items = iter::repeat_with(|| Item {
sum: Cell::new(0),
end_index: Cell::new(0),
})
.take(n)
.collect::<Box<_>>();

let mut result = vec![0; n];
let mut max_sum = 0;

result
.iter_mut()
.zip(&remove_queries)
.rev()
.for_each(|(target, &index)| {
*target = max_sum as _;

let mut index = index as u32 as usize;
let mut end = &items[index];
let mut sum = u64::from(nums[index] as u32);
let other_end;

'block: {
let (other, other_sum) = match (
items.get(index.wrapping_sub(1)).and_then(Self::filter),
items.get(index + 1).and_then(Self::filter),
) {
(None, None) => {
other_end = end;

break 'block;
}
(None, Some((other, other_sum))) | (Some((other, other_sum)), None) => (other, other_sum),
(Some((left, left_sum)), Some((right, right_sum))) => {
index = left.end_index.get();
end = &items[index];
sum += left_sum;

(right, right_sum)
}
};

let other_end_index = other.end_index.get();

other_end = &items[other_end_index];

sum += other_sum;

end.end_index.set(other_end_index);
end.sum.set(sum);
}

other_end.end_index.set(index);
other_end.sum.set(sum);

max_sum = max_sum.max(sum);
});

result
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn maximum_segment_sum(nums: Vec<i32>, remove_queries: Vec<i32>) -> Vec<i64> {
Self::maximum_segment_sum(nums, remove_queries)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}

0 comments on commit f770836

Please sign in to comment.