use std::fs::File;
use std::io::{*};
use std::cmp::max;
struct Segment {
val : i32,
lft : Option<Box<Segment>>,
rht : Option<Box<Segment>>,
}
impl Segment {
fn new(l : usize, r : usize, data : &Vec<i32>) -> Segment {
if l == r {
return Segment {
val : data[l],
lft : None,
rht : None
}
}
let mid : usize = (l + r) >> 1;
let segment_lft = Segment::new(l, mid, data);
let segment_rht = Segment::new(mid + 1, r, data);
let value = max(segment_lft.val, segment_rht.val);
Segment {
val : value,
lft : Some(Box::new(segment_lft)),
rht : Some(Box::new(segment_rht))
}
}
fn query(self : &mut Segment, l : usize, r : usize, gl : usize, gr : usize) -> i32 {
if r < gl || gr < l {
return 0;
}
if gl <= l && r <= gr {
return self.val;
}
let mid : usize = (l + r) >> 1;
let mut lft : Box<Segment> = self.lft.take().unwrap();
let mut rht : Box<Segment> = self.rht.take().unwrap();
let candidate_lft : i32 = lft.query(l, mid, gl, gr);
let candidate_rht : i32 = rht.query(mid + 1, r, gl, gr);
let res : i32 = max(candidate_lft, candidate_rht);
self.lft = Some(lft);
self.rht = Some(rht);
return res;
}
fn update(self : &mut Segment, l : usize, r : usize, gl : usize, gr : usize, new_value : i32) {
if r < gl || gr < l {
return;
}
if l == r {
self.val = new_value;
return;
}
let mid : usize = (l + r) >> 1;
let mut lft : Box<Segment> = self.lft.take().unwrap();
let mut rht : Box<Segment> = self.rht.take().unwrap();
lft.update(l, mid, gl, gr, new_value);
rht.update(mid + 1, r, gl, gr, new_value);
self.val = max(lft.val, rht.val);
self.lft = Some(lft);
self.rht = Some(rht);
return;
}
}
struct SegmentTree {
head : Segment,
len : usize,
}
impl SegmentTree {
fn new(data : &Vec<i32>) -> SegmentTree {
SegmentTree {
head : Segment::new(0, data.len() - 1, data),
len : data.len()
}
}
fn query(self : &mut SegmentTree, lft : usize, rht : usize) -> i32 {
return self.head.query(0, self.len - 1, lft, rht);
}
fn update(self : &mut SegmentTree, index : usize, new_value : i32) {
self.head.update(0, self.len - 1, index, index, new_value);
}
}
fn main() {
let mut input = BufReader::new(File::open("arbint.in").unwrap());
let mut output = BufWriter::new(File::create("arbint.out").unwrap());
let mut line = String::new();
input.read_line(&mut line).unwrap();
let args : Vec<usize> = line.trim().split(" ").map(|x| x.parse().unwrap()).collect();
let (_n, m) = (args[0], args[1]);
let mut line = String::new();
input.read_line(&mut line).unwrap();
let args : Vec<i32> = line.trim().split(" ").map(|x| x.parse().unwrap()).collect();
let mut st = SegmentTree::new(&args);
for _query in 0..m {
let mut line = String::new();
input.read_line(&mut line).unwrap();
let args : Vec<usize> = line.trim().split(" ").map(|x| x.parse().unwrap()).collect();
let op = args[0];
if op == 0 {
let (lft, rht) = (args[1], args[2]);
writeln!(output, "{}", st.query(lft - 1, rht - 1)).unwrap();
}
if op == 1 {
let (ind, val) = (args[1], args[2]);
st.update(ind - 1, val as i32);
}
}
}