Cod sursa(job #2752240)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 17 mai 2021 10:33:53
Problema Arbori de intervale Scor 100
Compilator rs Status done
Runda Arhiva educationala Marime 3.64 kb
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);
        }
    }
}