diff --git a/src/problem/mod.rs b/src/problem/mod.rs index 1277db5..ff08760 100644 --- a/src/problem/mod.rs +++ b/src/problem/mod.rs @@ -247,4 +247,5 @@ mod p997_find_the_town_judge; mod p2207_maximize_number_of_subsequences_in_a_string; mod p2306_naming_a_company; mod p2535_difference_between_element_sum_and_digit_sum_of_an_array; -mod p2516_take_k_of_each_character_from_left_and_right; \ No newline at end of file +mod p2516_take_k_of_each_character_from_left_and_right; +mod p2286_booking_concert_tickets_in_groups; \ No newline at end of file diff --git a/src/problem/p2286_booking_concert_tickets_in_groups.rs b/src/problem/p2286_booking_concert_tickets_in_groups.rs new file mode 100644 index 0000000..3a3a9ca --- /dev/null +++ b/src/problem/p2286_booking_concert_tickets_in_groups.rs @@ -0,0 +1,153 @@ +/** + * [2286] Booking Concert Tickets in Groups + */ +pub struct Solution {} + + +// submission codes start here + +struct BookMyShow { + row_count: i32, + column_count: i32, + min_tree: Vec, + sum_tree: Vec +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl BookMyShow { + fn new(n: i32, m: i32) -> Self { + let segement_depth = n as usize * 4; + Self { + row_count: n, + column_count: m, + min_tree: vec![0; segement_depth], + sum_tree: vec![0; segement_depth] + } + } + + fn modify(&mut self, i: usize, l: i32, r: i32, index: i32, val: i32) { + if l == r { + self.min_tree[i] = val; + self.sum_tree[i] = val as i64; + return; + } + + let middle = (l + r) / 2; + if index <= middle { + self.modify(i * 2, l, middle, index, val); + } else { + self.modify(i * 2 + 1, middle + 1, r, index, val) + } + + self.min_tree[i] = self.min_tree[i * 2].min(self.min_tree[i * 2 + 1]); + self.sum_tree[i] = self.sum_tree[i * 2] + self.sum_tree[i * 2 + 1]; + } + + fn query_min_row(&self, i: usize, l: i32, r: i32, val: i32) -> i32 { + if l == r { + return if self.min_tree[i] > val { + self.row_count + } else { + l + } + } + + let middle = (l + r) / 2; + if self.min_tree[i * 2] <= val { + self.query_min_row(i * 2, l, middle, val) + } else { + self.query_min_row(i * 2 + 1, middle + 1, r, val) + } + } + + fn query_sum(&self, i: usize, l: i32, r: i32, target_left: i32, target_right: i32) -> i64 { + if target_left <= l && r <= target_right { + return self.sum_tree[i]; + } + + let middle = (l + r) / 2; + let mut result = 0; + + if middle >= target_left { + result += self.query_sum(i * 2, l, middle, target_left, target_right) + } + + if middle + 1 <= target_right { + result += self.query_sum(i * 2 + 1, middle + 1, r, target_left, target_right); + } + + result + } + + fn gather(&mut self, k: i32, max_row: i32) -> Vec { + let target_row = self.query_min_row(1, 0, self.row_count - 1, self.column_count - k); + if target_row > max_row { + return vec![]; + } + + let used = self.query_sum(1, 0, self.row_count - 1, target_row, target_row) as i32; + self.modify(1, 0, self.row_count - 1, target_row, used + k); + vec![target_row, used] + } + + fn scatter(&mut self, k: i32, max_row: i32) -> bool { + let used = self.query_sum(1, 0, self.row_count - 1, 0, max_row); + if ((max_row + 1) as i64 * self.column_count as i64) - used < k as i64 { + return false; + } + + let mut target_row = self.query_min_row(1, 0, self.row_count - 1, self.column_count - 1); + let mut k = k; + loop { + let used = self.query_sum(1, 0, self.row_count - 1, target_row, target_row) as i32; + if self.column_count - used >= k { + self.modify(1, 0, self.row_count - 1, target_row, used + k); + break; + } + + k -= self.column_count - used; + self.modify(1, 0, self.row_count - 1, target_row, self.column_count); + target_row += 1; + } + + true + } +} + +/** + * Your BookMyShow object will be instantiated and called as such: + * let obj = BookMyShow::new(n, m); + * let ret_1: Vec = obj.gather(k, maxRow); + * let ret_2: bool = obj.scatter(k, maxRow); + */ + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_2286_1() { + let mut show = BookMyShow::new(2, 5); + + assert_eq!(vec![0,0], show.gather(4, 0)); + assert_eq!(Vec::::new(), show.gather(2, 0)); + assert!(show.scatter(5, 1)); + assert!(!show.scatter(5, 1)); + } + + #[test] + fn test_2286_2() { + let mut show = BookMyShow::new(5, 9); + + assert_eq!(Vec::::new(), show.gather(10, 1)); + assert!(show.scatter(3, 3)); + assert_eq!(vec![1, 0], show.gather(9, 1)); + assert_eq!(Vec::::new(), show.gather(10, 2)); + assert_eq!(vec![0, 3], show.gather(2, 0)); + } +}