use std::io::{BufWriter, Write, read_to_string, stdin, stdout}; const MOD: usize = 1_000_000_007; /* IMPLEMENTATION MONOID-FN */ pub trait MonoidFn { fn call(&self, a: &T, b: &T) -> T; fn identity(&self) -> T; } /* IMPLEMENTATION SEG-TREE ON MONOID-FN */ struct SegTree where F: MonoidFn, { pub op: F, size: usize, tree: Vec, } impl SegTree where F: MonoidFn, { fn new(arr: &Vec, 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 MulMod; impl MonoidFn for MulMod { fn call(&self, a: &usize, b: &usize) -> usize { (a * b) % MOD } fn identity(&self) -> usize { 1 } } fn main() { let temp = read_to_string(stdin()).unwrap(); let mut iter = temp .split_ascii_whitespace() .map(|x| x.parse::().unwrap()); let (n, m, k) = ( iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap(), ); let op = MulMod; let arr = (0..n).map(|_| iter.next().unwrap()).collect::>(); let mut out = BufWriter::new(stdout()); let mut segtr = SegTree::new(&arr, op); for _ in 0..m + k { 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).unwrap(); } else { segtr.modify(0, 0, n, b, &c); } } }