Problem:
Score : 500 points

Problem Statement

There is an infinitely long street that runs west to east, which we consider as a number line.

There are N roadworks scheduled on this street.
The i-th roadwork blocks the point at coordinate X_i from time S_i - 0.5 to time T_i - 0.5.

Q people are standing at coordinate 0. The i-th person will start the coordinate 0 at time D_i, continue to walk with speed 1 in the positive direction and stop walking when reaching a blocked point.

Find the distance each of the Q people will walk.

Constraints

All values in input are integers.

1 \leq N, Q \leq 2 \times 10^5

0 \leq S_i < T_i \leq 10^9

1 \leq X_i \leq 10^9

0 \leq D_1 < D_2 < ... < D_Q \leq 10^9

If i \neq j and X_i = X_j, the intervals [S_i, T_i) and [S_j, T_j) do not overlap.

Input

Input is given from Standard Input in the following format:

N Q
S_1 T_1 X_1
:
S_N T_N X_N
D_1
:
D_Q

Output

Print Q lines. The i-th line should contain the distance the i-th person will walk or -1 if that person walks forever.

Sample Input 1

4 6
1 3 2
7 13 10
18 20 13
3 4 2
0
1
2
3
5
8

Sample Output 1

2
2
10
-1
13
-1

The first person starts coordinate 0 at time 0 and stops walking at coordinate 2 when reaching a point blocked by the first roadwork at time 2.

The second person starts coordinate 0 at time 1 and reaches coordinate 2 at time 3. The first roadwork has ended, but the fourth roadwork has begun, so this person also stops walking at coordinate 2.

The fourth and sixth persons encounter no roadworks while walking, so they walk forever. The output for these cases is -1.

Solution in Rust (1.15.1) (judge verdict: Accepted)

#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    input!{
        n: usize, q: usize,
        stx: [(i64,i64,i64);n],
        d: [i64;q]
    }

    let mut coords = skiplist::Skiplist::new();

    let mut events = vec![];
    for (s,t,x) in stx {
        events.push((s-x,1,x));
        events.push((t-x,0,x));
    }
    for i in 0..q {
        events.push((d[i], 2, i as i64));
    }

    events.sort();

    let mut ans = vec![0; q];

    for ev in events {
        match ev {
            (_, 1, x) => {
                coords.insert(x);
            },
            (_, 0, x) => {
                coords.remove(&x);
            },
            (_, 2, i) => {
                let i = i as usize;
                let mut it = coords.iter();
                if let Some(fi) = it.next() {
                    ans[i] = fi;
                } else {
                    ans[i] = -1;
                }
            },
            _ => {
                unreachable!()
            }
        }
    }

    for x in ans {
        println!("{}", x);
    }
}
mod skiplist {
    use std;
    use std::cell::{Cell, RefCell};
    use std::collections::{BTreeMap, BTreeSet};
    use std::fmt;
    use std::rc::Rc;
    struct RandGen {
        x: u64,
    }
    impl RandGen {
        fn new(seed: u64) -> RandGen {
            RandGen { x: seed }
        }
        fn next(&mut self) -> u64 {
            const a: u64 = 1103515245;
            const b: u64 = 12345;
            const m: u64 = 1 << 32;
            self.x = (a * self.x + b) % m;
            self.x
        }
    }
    pub struct Skiplist<T> {
        max_height: Option<usize>,
        left_sentinel: Rc<RefCell<SkipNode<T>>>,
        right_sentinel: Rc<RefCell<SkipNode<T>>>,
        rand_gen: RandGen,
        traverse_stat: Cell<usize>,
        connect_stat: Cell<usize>,
    }
    impl Skiplist<usize> {
        fn print_graph(&self) {
            for level in (0..self.height()).rev() {
                let mut line = vec![];
                let mut cur = self.left_sentinel.clone();
                loop {
                    let next0 = cur.borrow().next[level].clone();
                    let next = next0.unwrap().clone();
                    if next.borrow().value.is_none() {
                        break;
                    } else {
                        cur = next.clone();
                        let v = cur.borrow().value.clone().unwrap();
                        line.push(v);
                    }
                }
                let mut ss = vec![];
                for x in line {
                    while ss.len() < x {
                        ss.push("--".to_string());
                    }
                    ss.push(format!("{:>02}", x));
                }
                println!("{}", ss.connect(","));
            }
            println!("");
        }
    }
    impl<T> Skiplist<T>
    where
        T: std::cmp::Ord + fmt::Debug + Clone,
    {
        pub fn new() -> Skiplist<T> {
            let left_sentinel = Rc::new(RefCell::new(SkipNode::sentinel()));
            let right_sentinel = Rc::new(RefCell::new(SkipNode::sentinel()));
            let sentinel_height = left_sentinel.borrow().height();
            for level in 0..sentinel_height {
                left_sentinel.borrow_mut().next[level] = Some(right_sentinel.clone());
                right_sentinel.borrow_mut().prev[level] = Some(left_sentinel.clone());
            }
            Skiplist {
                max_height: None,
                left_sentinel: left_sentinel,
                right_sentinel: right_sentinel,
                rand_gen: RandGen::new(0),
                traverse_stat: Cell::new(0),
                connect_stat: Cell::new(0),
            }
        }
        fn height(&self) -> usize {
            self.max_height.unwrap_or(33)
        }
        fn pick_height(&mut self) -> usize {
            let z = self.rand_gen.next();
            let mut k = 0;
            let mut m = 1;
            while z & m != 0 {
                k += 1;
                m <<= 1;
            }
            k + 1
        }
        pub fn insert(&mut self, x: T) -> bool {
            let mut paths = self.traverse(&x);
            if !paths.is_empty() {
                let next0 = paths[0].borrow().next[0].clone();
                let next = next0.unwrap();
                let found = next.borrow().value.as_ref() == Some(&x);
                if found {
                    return false;
                }
            }
            let new_height = self.pick_height();
            self.max_height = Some(std::cmp::max(self.max_height.unwrap_or(0), new_height));
            while paths.len() < new_height {
                paths.push(self.left_sentinel.clone());
            }
            let new_node = Rc::new(RefCell::new(SkipNode::new(x, new_height)));
            for level in 0..new_height {
                let prev = &paths[level];
                self.connect_stat.set(self.connect_stat.get() + 1);
                SkipNode::connect(prev, &new_node, level);
            }
            true
        }
        fn find_node(&self, x: &T) -> Option<Rc<RefCell<SkipNode<T>>>> {
            let paths = self.traverse(x);
            if paths.is_empty() {
                return None;
            }
            let next0 = paths[0].borrow().next[0].clone();
            let next = next0.unwrap();
            if next.borrow().value.as_ref() == Some(x) {
                Some(next)
            } else {
                None
            }
        }
        pub fn find(&self, x: &T) -> bool {
            self.find_node(x).is_some()
        }
        pub fn reset_stat(&self) {
            self.traverse_stat.set(0);
            self.connect_stat.set(0);
        }
        pub fn show_stat(&self) {
            println!("traverse: {}", self.traverse_stat.get());
            println!("connect: {}", self.connect_stat.get());
        }
        fn traverse(&self, x: &T) -> Vec<Rc<RefCell<SkipNode<T>>>> {
            if self.height() == 0 {
                return vec![];
            }
            let mut cur = self.left_sentinel.clone();
            let mut acc = vec![self.left_sentinel.clone(); self.height()];
            let mut level = self.height() - 1;
            loop {
                if level == 0 {
                    loop {
                        acc[level] = cur.clone();
                        let next0 = cur.borrow().next[level].clone();
                        let next = next0.unwrap();
                        if next.borrow().value.is_none()
                            || next.borrow().value.as_ref().unwrap() >= x
                        {
                            break;
                        } else {
                            cur = next.clone();
                            self.traverse_stat.set(self.traverse_stat.get() + 1);
                        }
                    }
                    break;
                }
                let next0 = cur.borrow().next[level].clone();
                let next = next0.unwrap();
                if next.borrow().value.is_none() || next.borrow().value.as_ref().unwrap() >= x {
                    acc[level] = cur.clone();
                    level -= 1;
                    continue;
                } else {
                    cur = next;
                    self.traverse_stat.set(self.traverse_stat.get() + 1);
                }
            }
            acc
        }
        fn traverse_rev(&self, x: &T) -> Vec<Rc<RefCell<SkipNode<T>>>> {
            if self.height() == 0 {
                return vec![];
            }
            let mut cur = self.right_sentinel.clone();
            let mut acc = vec![self.right_sentinel.clone(); self.height()];
            let mut level = self.height() - 1;
            loop {
                if level == 0 {
                    loop {
                        acc[level] = cur.clone();
                        let next = cur.borrow().prev[level].clone().unwrap();
                        if next.borrow().value.is_none()
                            || next.borrow().value.as_ref().unwrap() <= x
                        {
                            break;
                        } else {
                            cur = next.clone();
                        }
                    }
                    break;
                }
                let next = cur.borrow().prev[level].clone().unwrap();
                if next.borrow().value.is_none() || next.borrow().value.as_ref().unwrap() <= x {
                    acc[level] = cur.clone();
                    level -= 1;
                    continue;
                } else {
                    cur = next;
                }
            }
            acc
        }
        pub fn remove(&mut self, x: &T) -> bool {
            let node = self.find_node(x);
            if node.is_none() {
                return false;
            }
            let node = node.unwrap();
            node.borrow_mut().remove();
            true
        }
        #[doc = "iterator in range [x,]"]
        pub fn ge_iter(&self, x: &T) -> Range<T> {
            let f = self.traverse(x)[0].clone();
            Range {
                forward: true,
                f: f,
                b: self.right_sentinel.clone(),
            }
        }
        #[doc = "iterator in range [,x]"]
        pub fn le_iter(&self, x: &T) -> Range<T> {
            let b = self.traverse_rev(x)[0].clone();
            Range {
                forward: false,
                f: self.left_sentinel.clone(),
                b: b,
            }
        }
        #[doc = "iterator in range [..]"]
        pub fn iter(&self) -> Range<T> {
            Range {
                forward: true,
                f: self.left_sentinel.clone(),
                b: self.right_sentinel.clone(),
            }
        }
    }
    pub struct Range<T> {
        forward: bool,
        f: Rc<RefCell<SkipNode<T>>>,
        b: Rc<RefCell<SkipNode<T>>>,
    }
    impl<T: Clone> Iterator for Range<T> {
        type Item = T;
        fn next(&mut self) -> Option<Self::Item> {
            let next0 = if self.forward {
                self.f.borrow().next[0].clone()
            } else {
                self.b.borrow().prev[0].clone()
            };
            if next0.is_none() {
                return None;
            }
            let next = next0.unwrap();
            if self.forward {
                self.f = next;
                self.f.borrow().value.clone()
            } else {
                self.b = next;
                self.b.borrow().value.clone()
            }
        }
    }
    impl<T: Clone> DoubleEndedIterator for Range<T> {
        fn next_back(&mut self) -> Option<Self::Item> {
            let next0 = if self.forward {
                self.b.borrow().prev[0].clone()
            } else {
                self.f.borrow().next[0].clone()
            };
            if next0.is_none() {
                return None;
            }
            let next = next0.unwrap();
            if self.forward {
                self.b = next;
                self.b.borrow().value.clone()
            } else {
                self.f = next;
                self.f.borrow().value.clone()
            }
        }
    }
    impl<T> fmt::Debug for Skiplist<T>
    where
        T: fmt::Debug + Clone + std::cmp::Ord,
    {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let v: Vec<T> = self.iter().collect();
            writeln!(f, "{:?}", v);
            Ok(())
        }
    }
    struct SkipNode<T> {
        value: Option<T>,
        prev: Vec<Option<Rc<RefCell<SkipNode<T>>>>>,
        next: Vec<Option<Rc<RefCell<SkipNode<T>>>>>,
    }
    impl<T> fmt::Debug for SkipNode<T>
    where
        T: fmt::Debug + std::cmp::Ord,
    {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            writeln!(f, "{:?}, {:?}", self.value, self.height());
            Ok(())
        }
    }
    impl<T> SkipNode<T>
    where
        T: std::cmp::Ord + fmt::Debug,
    {
        fn sentinel() -> SkipNode<T> {
            SkipNode {
                value: None,
                prev: vec![None; 33],
                next: vec![None; 33],
            }
        }
        fn new(value: T, height: usize) -> SkipNode<T> {
            SkipNode {
                value: Some(value),
                prev: vec![None; height],
                next: vec![None; height],
            }
        }
        fn height(&self) -> usize {
            self.next.len()
        }
        fn remove(&mut self) {
            for level in 0..self.height() {
                let prev_node = self.prev[level].clone().unwrap();
                let next_node = self.next[level].clone().unwrap();
                next_node.borrow_mut().prev[level] = Some(prev_node.clone());
                prev_node.borrow_mut().next[level] = Some(next_node.clone());
            }
        }
        fn connect(x: &Rc<RefCell<Self>>, y: &Rc<RefCell<Self>>, level: usize) {
            let x_next = x.borrow().next[level].clone().unwrap();
            x.borrow_mut().next[level] = Some(y.clone());
            y.borrow_mut().prev[level] = Some(x.clone());
            y.borrow_mut().next[level] = Some(x_next.clone());
            x_next.borrow_mut().prev[level] = Some(y.clone());
        }
    }

    use std::collections::HashMap;
    pub struct Multiset<T> {
        sl: Skiplist<T>,
        counting: HashMap<T, usize>,
    }
    impl<T> Multiset<T>
    where
        T: Ord + fmt::Debug + Clone + std::hash::Hash,
    {
        pub fn new() -> Multiset<T> {
            Multiset {
                sl: Skiplist::new(),
                counting: HashMap::new(),
            }
        }
        pub fn insert(&mut self, x: T) {
            self.sl.insert(x.clone());
            *self.counting.entry(x).or_insert(0) += 1;
        }
        pub fn counting(&self, x: &T) -> usize {
            self.counting.get(x).cloned().unwrap_or(0)
        }
        pub fn remove(&mut self, x: &T) -> bool {
            let cnt = self.counting(x);
            if cnt == 0 {
                return false;
            }
            if cnt >= 2 {
                *self.counting.get_mut(x).unwrap() -= 1;
            } else if cnt == 1 {
                self.counting.remove(x);
                self.sl.remove(x);
            }
            return true;
        }
        pub fn unwrap(&self) -> &Skiplist<T> {
            &self.sl
        }
    }
}