complete 14428.rs

This commit is contained in:
2026-04-03 16:59:59 +09:00
parent f5141fc02c
commit 9b79eb05ba

View File

@@ -0,0 +1,148 @@
use std::io::{BufWriter, Write, read_to_string, stdin, stdout};
const MOD: usize = 1_000_000_007;
/*
IMPLEMENTATION MONOID-FN
*/
pub trait MonoidFn<T> {
fn call(&self, a: &T, b: &T) -> T;
fn identity(&self) -> T;
}
/*
IMPLEMENTATION SEG-TREE ON MONOID-FN<T>
*/
struct SegTree<T: Clone, F>
where
F: MonoidFn<T>,
{
pub op: F,
size: usize,
tree: Vec<T>,
}
impl<T: Clone, F> SegTree<T, F>
where
F: MonoidFn<T>,
{
fn new(arr: &Vec<T>, op: F) -> Self {
let size = arr.len();
let mut tree = vec![op.identity(); size * 4];
let mut stack = vec![]; // (inst, index, [lo, hi))
stack.push((1, 0, 0, size)); // 빼면서 업데이트
stack.push((0, 0, 0, size)); // 넣기
while !stack.is_empty() {
let (inst, index, lo, hi) = stack.pop().unwrap();
if inst == 0 {
if hi - lo == 1 {
tree[index] = arr[lo].clone();
} else {
let mid = (lo + hi) / 2;
let left_index = index * 2 + 1;
let right_index = index * 2 + 2;
stack.push((1, left_index, lo, mid));
stack.push((0, left_index, lo, mid));
stack.push((1, right_index, mid, hi));
stack.push((0, right_index, mid, hi));
}
} else {
if hi - lo == 1 {
continue;
} else {
let left_index = index * 2 + 1;
let right_index = index * 2 + 2;
tree[index] = op.call(&tree[left_index], &tree[right_index]);
}
}
}
SegTree { op, size, tree }
}
fn query(&self, idx: usize, lo: usize, hi: usize, qlo: usize, qhi: usize) -> T {
if qlo >= hi || qhi <= lo {
self.op.identity()
} else if qlo <= lo && hi <= qhi {
self.tree[idx].clone()
} else {
let mid = (lo + hi) / 2;
let left_value = self.query(idx * 2 + 1, lo, mid, qlo, qhi);
let right_value = self.query(idx * 2 + 2, mid, hi, qlo, qhi);
self.op.call(&left_value, &right_value)
}
}
fn modify(&mut self, idx: usize, lo: usize, hi: usize, pos: usize, val: &T) {
if pos < lo || pos >= hi {
return;
}
if hi - lo == 1 {
self.tree[idx] = val.clone();
return;
}
let mid = (lo + hi) / 2;
self.modify(idx * 2 + 1, lo, mid, pos, val);
self.modify(idx * 2 + 2, mid, hi, pos, val);
self.tree[idx] = self
.op
.call(&self.tree[idx * 2 + 1], &self.tree[idx * 2 + 2]);
}
}
struct MinIdx;
impl MonoidFn<(usize, usize)> for MinIdx {
fn call(&self, a: &(usize, usize), b: &(usize, usize)) -> (usize, usize) {
if a.1 < b.1 {
(a.0, a.1)
} else if a.1 == b.1 {
if a.0 <= b.0 { (a.0, a.1) } else { (b.0, b.1) }
} else {
(b.0, b.1)
}
}
fn identity(&self) -> (usize, usize) {
(usize::MAX, usize::MAX)
}
}
fn main() {
let temp = read_to_string(stdin()).unwrap();
let mut iter = temp
.split_ascii_whitespace()
.map(|x| x.parse::<usize>().unwrap());
let n = iter.next().unwrap();
let op = MinIdx;
let arr = (0..n)
.map(|i| (i + 1, iter.next().unwrap()))
.collect::<Vec<_>>();
let m = iter.next().unwrap();
let mut out = BufWriter::new(stdout());
let mut segtr = SegTree::new(&arr, op);
for _ in 0..m {
let (a, b, c) = (
iter.next().unwrap(),
iter.next().unwrap() - 1,
iter.next().unwrap(),
);
if a == 2 {
let res = segtr.query(0, 0, n, b, c);
writeln!(out, "{}", res.0).unwrap();
} else {
segtr.modify(0, 0, n, b, &(b + 1, c));
}
}
}