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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

partial class Solver {
    public class Data {
        public int Id { get; set; }
        public int Value { get; set; }
    }

    public void Run() {
        var N = ni();
        var Q = ni();
        var S = new int[N];
        var T = new int[N];
        var X = new int[N];
        for (int i = 0; i < N; i++) {
            S[i] = ni();
            T[i] = ni();
            X[i] = ni();
        }
        var D = ni(Q);

        var tree = new RangeUpdateSegmentTree<int>(Math.Min, int.MaxValue);
        tree.Build(Q, i => int.MaxValue);

        for (int i = 0; i < N; i++) {
            //var begin = dic.GetIndex(S[i] - X[i]);
            //var end = dic.GetIndex(T[i] - X[i]);
            var begin = ArrayUtility.LowerBound(D, S[i] - X[i]);
            var end = ArrayUtility.UpperBound(D, T[i] - X[i] - 1);

            tree.RangeMerge(begin, end, X[i]);
        }

        for (int i = 0; i < Q; i++) {
            var ans = tree[i];
            if (ans == int.MaxValue) ans = -1;
            cout.WriteLine(ans);
        }
    }
}


static public class ArrayUtility {
    static public int LowerBound<T>(IList<T> A, T x) {
        return LowerBound(A, 0, A.Count, x);
    }

    static public int LowerBound<T>(IList<T> A, T x, IComparer<T> comparer) {
        return LowerBound(A, 0, A.Count, x, comparer);
    }

    static public int LowerBound<T>(IList<T> A, int start, int end, T x) {
        return LowerBound(A, start, end, x, Comparer<T>.Default);
    }

    static public int LowerBound<T>(IList<T> A, int start, int end, T x, IComparer<T> comparer) {
        int lower = start, upper = end - 1;
        int result = end;
        while (lower <= upper) {
            int pos = (lower + upper) / 2;
            if (comparer.Compare(x, A[pos]) <= 0) {
                result = pos;
                upper = pos - 1;
            } else
                lower = pos + 1;
        }

        return result;
    }

    static public int UpperBound<T>(IList<T> A, T x) {
        return UpperBound(A, 0, A.Count, x);
    }

    static public int UpperBound<T>(IList<T> A, T x, IComparer<T> comparer) {
        return UpperBound(A, 0, A.Count, x, comparer);
    }

    static public int UpperBound<T>(IList<T> A, int start, int end, T x) {
        return UpperBound(A, start, end, x, Comparer<T>.Default);
    }

    static public int UpperBound<T>(IList<T> A, int start, int end, T x, IComparer<T> comparer) {
        int lower = start, upper = end - 1;
        int result = end;
        while (lower <= upper) {
            int pos = (lower + upper) / 2;
            if (comparer.Compare(x, A[pos]) < 0) {
                result = pos;
                upper = pos - 1;
            } else
                lower = pos + 1;
        }

        return result;
    }
}
public class IndexDictionary<T> {
    private readonly Dictionary<T, int> _toIndex;
    private readonly T[] _array;

    public IndexDictionary(IEnumerable<T> source) : this(source, Comparer<T>.Default) { }

    public IndexDictionary(IEnumerable<T> source, IComparer<T> comparer) {
        _array = source.ToArray();
        Array.Sort(_array, comparer);
        _toIndex = new Dictionary<T, int>(_array.Length);
        int index = -1;
        foreach (var x in _array) _toIndex[x] = ++index;
    }

    public int Count { get { return _array.Length; } }

    public T this[int index] { get { return _array[index]; } }

    public int GetIndex(T value) { return _toIndex[value]; }
}

public class IndexDictionaryFactory {
    public static IndexDictionary<T> Create<T>(IEnumerable<T> source) {
        return new IndexDictionary<T>(source);
    }
}

public sealed class RangeUpdateSegmentTree<TMonoid> {
    public int Count { get; private set; }
    private TMonoid[] _node;
    private readonly TMonoid _identity;
    private readonly Func<TMonoid, TMonoid, TMonoid> _merge;

    public RangeUpdateSegmentTree(Func<TMonoid, TMonoid, TMonoid> merge, TMonoid identity) {
        _merge = merge;
        _identity = identity;
    }

    public void Build(IList<TMonoid> array) {
        Build(array.Count, i => array[i]);
    }

    public void Build(int n, Func<int, TMonoid> create) {
        Count = n;

        _node = new TMonoid[2 * Count];

        for (int i = 0; i < n; i++) {
            _node[i + Count] = create(i);
        }

        for (int i = Count - 1; i > 0; i--) {
            _node[i] = _merge(_node[i << 1], _node[i << 1 | 1]);
        }
    }

    public TMonoid Get(int index) {
        int p = index + Count;
        var val = _identity;
        while (p > 0) {
            val = _merge(val, _node[p]);
            p >>= 1;
        }
        return val;
    }

    public void RangeMerge(int begin, int end, TMonoid val) {
        int l = begin + Count;
        int r = end + Count - 1;
        for (; l <= r; l >>= 1, r >>= 1) {
            if ((l & 1) == 1) { _node[l] = _merge(val, _node[l]); l++; }
            if ((r & 1) == 0) { _node[r] = _merge(_node[r], val); r--; }
        }
    }

    public TMonoid this[int index] {
        get { return Get(index); }
    }
};

// PREWRITEN CODE BEGINS FROM HERE
internal partial class Solver : Scanner {
    public static void Main(string[] args) {
#if LOCAL
        byte[] inputBuffer = new byte[1000000];
        var inputStream = Console.OpenStandardInput(inputBuffer.Length);
        using (var reader = new StreamReader(inputStream, Console.InputEncoding, false, inputBuffer.Length)) {
            Console.SetIn(reader);
            new Solver(Console.In, Console.Out).Run();
        }
#else
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver(Console.In, Console.Out).Run();
        Console.Out.Flush();
#endif
    }

#pragma warning disable IDE0052
    private readonly TextReader cin;
    private readonly TextWriter cout;
#pragma warning restore IDE0052

    public Solver(TextReader reader, TextWriter writer)
        : base(reader) {
        cin = reader;
        cout = writer;
    }
    public Solver(string input, TextWriter writer)
        : this(new StringReader(input), writer) {
    }

#pragma warning disable IDE1006
#pragma warning disable IDE0051
    private int ni() { return NextInt(); }
    private int[] ni(int n) { return NextIntArray(n); }
    private long nl() { return NextLong(); }
    private long[] nl(int n) { return NextLongArray(n); }
    private double nd() { return NextDouble(); }
    private double[] nd(int n) { return NextDoubleArray(n); }
    private string ns() { return Next(); }
    private string[] ns(int n) { return NextArray(n); }
#pragma warning restore IDE1006
#pragma warning restore IDE0051
}

internal static class LinqPadExtension {
    [Conditional("DEBUG")]
    public static void Dump<T>(this T obj) {
#if DEBUG
        LINQPad.Extensions.Dump(obj);
#endif
    }
}

public class Scanner {
    private readonly TextReader Reader;
    private readonly CultureInfo ci = CultureInfo.InvariantCulture;

    private readonly char[] buffer = new char[2 * 1024];
    private int cursor = 0, length = 0;
    private string Token;
    private readonly StringBuilder sb = new StringBuilder(1024);

    public Scanner()
        : this(Console.In) {
    }

    public Scanner(TextReader reader) {
        Reader = reader;
    }

    public int NextInt() { return checked((int)NextLong()); }
    public long NextLong() {
        var s = Next();
        long r = 0;
        int i = 0;
        bool negative = false;
        if (s[i] == '-') {
            negative = true;
            i++;
        }
        for (; i < s.Length; i++) {
            r = r * 10 + (s[i] - '0');
#if DEBUG
            if (!char.IsDigit(s[i])) throw new FormatException();
#endif
        }
        return negative ? -r : r;
    }
    public double NextDouble() { return double.Parse(Next(), ci); }
    public string[] NextArray(int size) {
        string[] array = new string[size];
        for (int i = 0; i < size; i++) {
            array[i] = Next();
        }

        return array;
    }
    public int[] NextIntArray(int size) {
        int[] array = new int[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextInt();
        }

        return array;
    }

    public long[] NextLongArray(int size) {
        long[] array = new long[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextLong();
        }

        return array;
    }

    public double[] NextDoubleArray(int size) {
        double[] array = new double[size];
        for (int i = 0; i < size; i++) {
            array[i] = NextDouble();
        }

        return array;
    }

    public string Next() {
        if (Token == null) {
            if (!StockToken()) {
                throw new InvalidOperationException();
            }
        }
        var token = Token;
        Token = null;
        return token;
    }

    public bool HasNext() {
        if (Token != null) {
            return true;
        }

        return StockToken();
    }

    private bool StockToken() {
        while (true) {
            sb.Clear();
            while (true) {
                if (cursor >= length) {
                    cursor = 0;
                    if ((length = Reader.Read(buffer, 0, buffer.Length)) <= 0) {
                        break;
                    }
                }
                var c = buffer[cursor++];
                if (33 <= c && c <= 126) {
                    sb.Append(c);
                } else {
                    if (sb.Length > 0) break;
                }
            }

            if (sb.Length > 0) {
                Token = sb.ToString();
                return true;
            }

            return false;
        }
    }
}