Submission #32435428


Source Code Expand

Copy
use proconio::input;
fn main() {
input! {
w: usize,
n: usize,
l_r: [(usize, usize); n]
}
let mut seg_tree = SegTree::new(vec![0; w], max, |_val, _len, height| height);
for (l, r) in l_r {
let height = seg_tree.get_range(l-1, r-1);
// height+1
seg_tree.range_update(l-1, r-1, height+1);
println!("{}", seg_tree.get_range(l-1, r-1));
}
}
fn max(a: usize, b: usize) -> usize{
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
use proconio::input;

fn main() {
    input! {
		w: usize,
        n: usize,
		l_r: [(usize, usize); n]
    }

	let mut seg_tree = SegTree::new(vec![0; w], max, |_val, _len, height| height);

	for (l, r) in l_r {
		let height = seg_tree.get_range(l-1, r-1);
		// レンガの範囲の高さは height+1になる
		seg_tree.range_update(l-1, r-1, height+1);

		println!("{}", seg_tree.get_range(l-1, r-1));
	}
}

fn max(a: usize, b: usize) -> usize{
	if a < b {
		b
	} else {
		a
	}
}



use std::fmt::Debug;

#[allow(dead_code)]
pub struct SegTree<T, F, L, P>
where
	T: Clone + Copy + Debug,
	F: Fn(T, T) -> T,
	L: Fn(T, usize, P) -> T,
	P: Clone + Copy + Debug,
{
	size: usize,
	values: Vec<Option<T>>,
	ranges: Vec<Option<(usize, usize)>>,
	lazy_params: Vec<Option<P>>,
	operator: F,
	lazy_operator: L,
}

impl<T, F, L, P> SegTree<T, F, L, P>
where
	T: Clone + Copy + Debug,
	F: Fn(T, T) -> T,
	L: Fn(T, usize, P) -> T,
	P: Clone + Copy + Debug,
{
	pub fn new(values: Vec<T>, operator: F, lazy_operator: L) -> Self {
		let size = values.len();
		let tree_size = 2*size.next_power_of_two()-1;
		let vals = vec![None; tree_size];
		let ranges = vec![None; tree_size];

		let mut seg_tree = Self {
			size,
			values: vals,
			ranges,
			lazy_params: vec![None; tree_size],
			operator,
			lazy_operator,
		};

		for i in 0..size {
			let index_of_tree = seg_tree.index_of_tree(i);
			seg_tree.values[index_of_tree] = Some(values[i]);
			seg_tree.ranges[index_of_tree] = Some((i, i));
		}

		for i in 0..seg_tree.index_of_tree(0) {
			// 降順に更新
			let index = seg_tree.index_of_tree(0)-1-i;
			let children_index = seg_tree.children_index(index).unwrap();
			let v1 = seg_tree.values[children_index.0];
			let v2 = seg_tree.values[children_index.1];
			let val = seg_tree.eval(v1, v2);

			let range = if seg_tree.ranges[children_index.0].is_none() {
				None
			} else {
				let range_min = seg_tree.ranges[children_index.0].unwrap().0;
				let range_max = if seg_tree.ranges[children_index.1].is_none() {
					seg_tree.ranges[children_index.0].unwrap().1
				} else {
					seg_tree.ranges[children_index.1].unwrap().1
				};
				Some((range_min, range_max))
			};

			seg_tree.values[index] = val;
			seg_tree.ranges[index] = range;
		}


		seg_tree
	}

	pub fn get(&mut self, index: usize) -> T {
		self.get_range(index, index)
	}

	pub fn get_range(&mut self, left: usize, right: usize) -> T {
		self.get_range_sub(left, right, 0).unwrap()
	}

	fn get_range_sub(&mut self, left: usize, right: usize, index: usize) -> Option<T> {
		if self.ranges[index].is_none() {
			// 指定されたindexに要素が存在しない
			None
		} else {
			let current_range = self.ranges[index].unwrap();

			// 遅延評価
			self.lazy_eval(index);

			if self.children_index(index).is_none() {
				// 葉
				if left <= current_range.0 && current_range.0 <= right {
					self.values[index]
				} else {
					None
				}
			} else if left <= current_range.0 && current_range.1 <= right {
				// 現在の範囲が覆われている場合
				// 現在の範囲での値を返す
				self.values[index]
			} else if right < current_range.0 || current_range.1 < left {
				// 現在の範囲と共通部分がない
				None
			} else {
				// 現在の範囲と共通部分がある場合
				// 子供も調べる
				let val_left = self.get_range_sub(left, right, self.children_index(index).unwrap().0);
				let val_right = self.get_range_sub(left, right, self.children_index(index).unwrap().1);
				self.eval(
					val_left,
					val_right,
				)
			}
		}
	}

	pub fn update(&mut self, index: usize, value: T) {
		// 遅延評価を実行する
		self.get(index);

		let mut index = self.index_of_tree(index);
		self.values[index] = Some(value);

		while !self.parent_index(index).is_none() {
			index = self.parent_index(index).unwrap();
			let children = self.children_index(index).unwrap();
			self.values[index] = self.eval(self.values[children.0], self.values[children.1]);
		}
	}

	pub fn range_update(&mut self, left: usize, right: usize, params: P) {
		if let Some(_) = self.lazy_params[0] {
			// 遅延更新が残っているので伝播させる
			self.get_range(0, self.size-1);
		}

		self.range_update_sub(left, right, params, 0);
	}

	fn range_update_sub(&mut self, left: usize, right: usize, params: P, index: usize) {
		if let Some(current_range) = self.ranges[index] {
			if right < current_range.0 || current_range.1 < left {
				// 範囲外なら何もしない
				return;
			} else if left <= current_range.0 && current_range.1 <= right {
				// 完全に覆われているなら遅延配列に値を入れて評価
				self.lazy_params[index] = Some(params);
				self.lazy_eval(index);
			} else {
				// 子ノードから計算済みの値をもらう
				if let Some((index_c1, index_c2)) = self.children_index(index) {
					let range_c1 = self.ranges[index_c1];
					let range_c2 = self.ranges[index_c2];

					if let Some(range_c1) = range_c1 {
						let intersection_left = if left <= range_c1.0 {
							range_c1.0
						} else {
							left
						};
						let intersection_right = if right <= range_c1.1 {
							right
						} else {
							range_c1.1
						};

						if intersection_left <=  intersection_right {
							// 共通部分がある
							self.range_update_sub(intersection_left, intersection_right, params, index_c1);
						}
					}

					if let Some(range_c2) = range_c2 {
						let intersection_left = if left <= range_c2.0 {
							range_c2.0
						} else {
							left
						};
						let intersection_right = if right <= range_c2.1 {
							right
						} else {
							range_c2.1
						};
						if intersection_left <=  intersection_right {
							// 共通部分がある
							self.range_update_sub(intersection_left, intersection_right, params, index_c2);
						}
					}

					self.values[index] = self.eval(self.values[index_c1], self.values[index_c2]);
				}
			}
		}

	}

	fn lazy_eval(&mut self, index: usize) {
		let current_range = self.ranges[index].unwrap();
		if let Some(params) = self.lazy_params[index] {
			self.values[index] = Some((self.lazy_operator)(self.values[index].unwrap(), current_range.1 - current_range.0 + 1, params));
			self.lazy_params[index] = None;

			if let Some((index_c1, index_c2)) = self.children_index(index) {
				// 子に伝播する
				let range_c1 = self.ranges[index_c1];
				let range_c2 = self.ranges[index_c2];

				if let Some(_) = range_c1 {
					self.lazy_params[index_c1] = Some(params);
				}

				if let Some(_) = range_c2 {
					self.lazy_params[index_c2] = Some(params);
				}
			}
		}
	}

	fn eval(&self, v1: Option<T>, v2: Option<T>) -> Option<T> {
		if v1.is_none() {
			if v2.is_none() {
				None
			} else {
				v2
			}
		} else {
			if v2.is_none() {
				v1
			} else {
				Some((self.operator)(v1.unwrap(), v2.unwrap()))
			}
		}
	}

	fn children_index(&self, index: usize) -> Option<(usize, usize)> {
		if index >= self.values.len()/2 {
			None
		} else {
			Some((2*index+1, 2*index+2))
		}
	}

	fn parent_index(&self, index: usize) -> Option<usize> {
		if index == 0 {
			None
		} else {
			Some((index-1)/2)
		}
	}

	fn index_of_tree(&self, index: usize) -> usize {
		self.values.len()/2+index
	}
}


impl<T, F, L, P>Debug for SegTree<T, F, L, P>
where
	T: Clone + Copy + Debug,
	F: Fn(T, T) -> T,
	L: Fn(T, usize, P) -> T,
	P: Clone + Copy + Debug,
{
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		for i in 0..self.values.len() {
			if let Some(range) = self.ranges[i] {
				f.write_fmt(format_args!("[{}, {}] val: {:?}, lazy: {:?}\n", range.0, range.1, self.values[i], self.lazy_params[i])).unwrap();
			}
		}
		Ok(())
	}
}

Submission Info

Submission Time
Task 029 - Long Bricks(★5)
User Hirekatsu
Language Rust (1.42.0)
Score 5
Code Size 7978 Byte
Status AC
Exec Time 1195 ms
Memory 66824 KB

Judge Result

Set Name Sample Subtask1 Subtask2 Subtask3
Score / Max Score 0 / 0 1 / 1 1 / 1 3 / 3
Status
AC × 4
AC × 12
AC × 22
AC × 31
Set Name Test Cases
Sample subtask01_01_sample_01.txt, subtask01_01_sample_02.txt, subtask01_01_sample_03.txt, subtask02_01_sample_04.txt
Subtask1 subtask01_01_sample_01.txt, subtask01_01_sample_02.txt, subtask01_01_sample_03.txt, subtask01_02_max_01.txt, subtask01_03_random_01.txt, subtask01_03_random_02.txt, subtask01_03_random_03.txt, subtask01_03_random_04.txt, subtask01_03_random_05.txt, subtask01_04_special_01.txt, subtask01_04_special_02.txt, subtask01_04_special_03.txt
Subtask2 subtask01_01_sample_01.txt, subtask01_01_sample_02.txt, subtask01_01_sample_03.txt, subtask01_02_max_01.txt, subtask01_03_random_01.txt, subtask01_03_random_02.txt, subtask01_03_random_03.txt, subtask01_03_random_04.txt, subtask01_03_random_05.txt, subtask01_04_special_01.txt, subtask01_04_special_02.txt, subtask01_04_special_03.txt, subtask02_01_sample_04.txt, subtask02_02_max_02.txt, subtask02_05_random_01.txt, subtask02_05_random_02.txt, subtask02_05_random_03.txt, subtask02_05_random_04.txt, subtask02_05_random_05.txt, subtask02_06_special_01.txt, subtask02_06_special_02.txt, subtask02_06_special_03.txt
Subtask3 subtask01_01_sample_01.txt, subtask01_01_sample_02.txt, subtask01_01_sample_03.txt, subtask01_02_max_01.txt, subtask01_03_random_01.txt, subtask01_03_random_02.txt, subtask01_03_random_03.txt, subtask01_03_random_04.txt, subtask01_03_random_05.txt, subtask01_04_special_01.txt, subtask01_04_special_02.txt, subtask01_04_special_03.txt, subtask02_01_sample_04.txt, subtask02_02_max_02.txt, subtask02_05_random_01.txt, subtask02_05_random_02.txt, subtask02_05_random_03.txt, subtask02_05_random_04.txt, subtask02_05_random_05.txt, subtask02_06_special_01.txt, subtask02_06_special_02.txt, subtask02_06_special_03.txt, subtask03_02_max_03.txt, subtask03_07_random_01.txt, subtask03_07_random_02.txt, subtask03_07_random_03.txt, subtask03_08_special_01.txt, subtask03_08_special_02.txt, subtask03_08_special_03.txt, subtask03_08_special_04.txt, subtask03_08_special_05.txt
Case Name Status Exec Time Memory
subtask01_01_sample_01.txt AC 7 ms 2188 KB
subtask01_01_sample_02.txt AC 2 ms 2108 KB
subtask01_01_sample_03.txt AC 1 ms 2088 KB
subtask01_02_max_01.txt AC 26 ms 4104 KB
subtask01_03_random_01.txt AC 32 ms 3224 KB
subtask01_03_random_02.txt AC 13 ms 2508 KB
subtask01_03_random_03.txt AC 39 ms 2736 KB
subtask01_03_random_04.txt AC 40 ms 3188 KB
subtask01_03_random_05.txt AC 38 ms 3120 KB
subtask01_04_special_01.txt AC 31 ms 4112 KB
subtask01_04_special_02.txt AC 38 ms 4044 KB
subtask01_04_special_03.txt AC 37 ms 4112 KB
subtask02_01_sample_04.txt AC 52 ms 59480 KB
subtask02_02_max_02.txt AC 66 ms 59800 KB
subtask02_05_random_01.txt AC 61 ms 30968 KB
subtask02_05_random_02.txt AC 79 ms 59528 KB
subtask02_05_random_03.txt AC 92 ms 59724 KB
subtask02_05_random_04.txt AC 86 ms 59632 KB
subtask02_05_random_05.txt AC 63 ms 30948 KB
subtask02_06_special_01.txt AC 84 ms 59764 KB
subtask02_06_special_02.txt AC 86 ms 59800 KB
subtask02_06_special_03.txt AC 82 ms 59772 KB
subtask03_02_max_03.txt AC 449 ms 65688 KB
subtask03_07_random_01.txt AC 1145 ms 66624 KB
subtask03_07_random_02.txt AC 997 ms 37400 KB
subtask03_07_random_03.txt AC 1013 ms 65940 KB
subtask03_08_special_01.txt AC 845 ms 66704 KB
subtask03_08_special_02.txt AC 863 ms 66800 KB
subtask03_08_special_03.txt AC 314 ms 61916 KB
subtask03_08_special_04.txt AC 871 ms 66824 KB
subtask03_08_special_05.txt AC 1195 ms 66772 KB


2025-04-05 (Sat)
23:59:19 +00:00