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.



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


Sample output:
2
2
10
-1
13
-1

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.depth = (self.n - 1).bit_length()
        self.size = 1 << self.depth
        self.lazy = [self.e] * ((self.size << 1) + 1)

    def built(self, array):
        """
        arrayを初期値とするセグメント木を構築
        """
        for i in range(self.n):
            self.lazy[self.size + i] = array[i]

    def update(self, l, r, x):
        """
        半開区間 [l, r) の各々の要素 a に op(x, a)を作用させる （ 0-indexed ）　（ O(logN) ）
        """
        l += self.size
        r += self.size
        self.propagate(l//(l&-l))
        self.propagate((r//(r&-r))-1)
        while l < r:
            if r&1:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = self.op(x, self.lazy[r])
            if l&1:
                self.lazy[l] = self.op(x, self.lazy[l])
                l += 1
            l >>= 1
            r >>= 1

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        for k in range(i.bit_length()-1, 0,-1):
            x = i>>k
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 0-indexed ） ( O(logN) )
        """
        i += self.size
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        for a in self.lazy[self.size:self.size+self.n]:
            yield a

    def __str__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        return str(self.lazy[self.size:self.size + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.depth = (self.n - 1).bit_length()
        self.size = 1 << self.depth
        self.lazy = [self.e] * ((self.size << 1) + 1)

    def built(self, array):
        """
        arrayを初期値とするセグメント木を構築
        """
        for i in range(self.n):
            self.lazy[self.size + i] = array[i]

    def update(self, l, r, x):
        """
        半開区間 [l, r) の各々の要素 a に op(x, a)を作用させる （ 0-indexed ）　（ O(logN) ）
        """
        l += self.size
        r += self.size
        l0 = l//(l&-l)
        r0 = r//(r&-r)
        self.propagate(l0)
        self.propagate(r0-1)
        while l < r:
            if r&1:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = self.op(x, self.lazy[r])
            if l&1:
                self.lazy[l] = self.op(x, self.lazy[l])
                l += 1
            l >>= 1
            r >>= 1

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        for k in range(i.bit_length()-1, 0,-1):
            x = i>>k
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 0-indexed ） ( O(logN) )
        """
        i += self.size
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        for a in self.lazy[self.size:self.size+self.n]:
            yield a

    def __str__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        return str(self.lazy[self.size:self.size + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.depth = (self.n - 1).bit_length()
        self.size = 1 << self.depth
        self.lazy = [self.e] * ((self.size << 1) + 1)

    def built(self, array):
        """
        arrayを初期値とするセグメント木を構築
        """
        for i in range(self.n):
            self.lazy[self.size + i] = array[i]

    def update(self, l, r, x):
        """
        半開区間 [l, r) の各々の要素 a に op(x, a)を作用させる （ 0-indexed ）　（ O(logN) ）
        """
        l += self.size
        r += self.size
        l0 = l//(l&-l)
        r0 = r//(r&-r)
        self.propagate(l0)
        self.propagate(r0-1)
        while l < r:
            if r&1:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = self.op(x, self.lazy[r])
            if l&1:
                self.lazy[l] = self.op(x, self.lazy[l])
                l += 1
            l >>= 1
            r >>= 1

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        for k in range(self.depth, 0,-1):
            x = i>>k
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 0-indexed ） ( O(logN) )
        """
        i += self.size
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        for a in self.lazy[self.size:self.size+self.n]:
            yield a

    def __str__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        return str(self.lazy[self.size:self.size + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.depth = (self.n - 1).bit_length()
        self.size = 1 << self.depth
        self.lazy = [self.e] * ((self.size << 1) + 1)

    def built(self, array):
        """
        arrayを初期値とするセグメント木を構築
        """
        for i in range(self.n):
            self.lazy[self.size + i] = array[i]

    def update(self, l, r, x):
        """
        半開区間 [l, r) の各々の要素 a に op(x, a)を作用させる （ 0-indexed ）　（ O(logN) ）
        """
        l += self.size
        r += self.size
        self.propagate(l)
        self.propagate(r-1)
        while l < r:
            if r&1:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = self.op(x, self.lazy[r])
            if l&1:
                self.lazy[l] = self.op(x, self.lazy[l])
                l += 1
            l >>= 1
            r >>= 1

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        for k in range(self.depth,0,-1):
            x = i>>k
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 0-indexed ） ( O(logN) )
        """
        i += self.size
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        for a in self.lazy[self.size:self.size+self.n]:
            yield a

    def __str__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)|1] = self.op(self.lazy[x], self.lazy[(x<<1)|1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        return str(self.lazy[self.size:self.size + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.depth = (self.n - 1).bit_length()
        self.size = 1 << self.depth
        self.lazy = [self.e] * ((self.size << 1) + 1)

    def update(self, l, r, x):
        """
        半開区間 [l, r) の値を x に更新 （ 1-indexed ）　（ O(logN) ）
        """
        l += self.size
        r += self.size
        self.propagate(l)
        self.propagate(r-1)
        while l < r:
            if r&1:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = x
            if l&1:
                self.lazy[l] = x
                l += 1
            l = l // 2
            r = r // 2

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        for k in range(self.depth,0,-1):
            x = i>>k
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)+1] = self.lazy[x]
            self.lazy[x<<1] = self.lazy[x]
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 1-indexed ） ( O(logN) )
        """
        i += self.size
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)+1] = self.lazy[x]
            self.lazy[x<<1] = self.lazy[x]
            self.lazy[x] = self.e
        for a in self.lazy[self.size:self.size+self.n]:
            yield a

    def __str__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)+1] = self.lazy[x]
            self.lazy[x<<1] = self.lazy[x]
            self.lazy[x] = self.e
        return str(self.lazy[self.size:self.size + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        self.n = n
        self.op = op
        self.e = e
        self.depth = (self.n - 1).bit_length()
        self.size = 1 << self.depth
        self.lazy = [self.e] * ((self.size << 1) + 1)

    def update(self, l, r, x):
        l += self.size
        r += self.size
        self.propagate(l)
        self.propagate(r-1)
        while l < r:
            if r&1:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = self.op(x, self.lazy[r])
            if l&1:
                self.lazy[l] = self.op(x, self.lazy[l])
                l += 1
            l = l // 2
            r = r // 2

    def propagate(self, i):
        for k in range(self.depth,0,-1):
            x = i>>k
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)+1] = self.op(self.lazy[x], self.lazy[(x<<1)+1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e

    def get(self, i):
        i += self.size
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)+1] = self.op(self.lazy[x], self.lazy[(x<<1)+1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        for a in self.lazy[self.size:self.size+self.n]:
            yield a

    def __str__(self):
        for x in range(1, self.size):
            if self.lazy[x] == self.e:
                continue
            self.lazy[(x<<1)+1] = self.op(self.lazy[x], self.lazy[(x<<1)+1])
            self.lazy[x<<1] = self.op(self.lazy[x], self.lazy[x<<1])
            self.lazy[x] = self.e
        return str(self.lazy[self.size:self.size + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
from bisect import bisect_left as bl
class segtree:
    def __init__(self, nn):
        self.NN = nn
        self.XX = [0] * (2**(nn+1)-1)
    def getmax(self, i):
        j = 2**self.NN + i - 1
        ma = -1
        while j >= 0:
            ma = max(ma, self.XX[j])
            j = (j-1) // 2
        return -1 if ma <= 0 else INF - ma
    def updaterange(self, a, b, x):
        l = a + (1<<self.NN)
        r = b + (1<<self.NN)
        s = 0
        while l < r:
            if l%2:
                self.XX[l-1] = max(self.XX[l-1], x)
                l += 1
            if r%2:
                r -= 1
                self.XX[r-1] = max(self.XX[r-1], x)
            l >>= 1
            r >>= 1

N, Q = map(int, input().split())
st = segtree(18)
INF = 1<<50
X = []
D = []
for _ in range(N):
    s, t, x = map(int, input().split())
    X.append((s, t, x))
for _ in range(Q):
    D.append(int(input()))

for s, t, x in X:
    st.updaterange(bl(D, s-x), bl(D, t-x), INF-x)
for i in range(Q):
    print(st.getmax(i))

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.size = 1 << (self.n - 1).bit_length()
        self.lazy = [self.e] * (self.size << 1)

    def update(self, l, r, x):
        """
        半開区間 [l, r) の値を x に更新 （ 0-indexed ）　（ O(logN) ）
        """
        l += (self.size - 1)
        r += (self.size - 1)
        self.propagate(l)
        self.propagate(r-1)
        while l < r:
            if r&1 == 0:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = x
            if l&1 == 0:
                self.lazy[l] = x
                l += 1
            l = (l - 1) // 2
            r = (r - 1) // 2

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        tmp = []
        while i>0:
            i -= 1
            i >>= 1
            tmp.append(i)
        for x in reversed(tmp):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.lazy[x]
            self.lazy[2*x+2] = self.lazy[x]
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 0-indexed ） ( O(logN) )
        """
        i += (self.size - 1)
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(self.size-1):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.lazy[x]
            self.lazy[2*x+2] = self.lazy[x]
            self.lazy[x] = self.e
        for a in self.lazy[self.size-1:self.size-1+self.n]:
            yield a

    def __str__(self):
        for x in range(self.size-1):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.lazy[x]
            self.lazy[2*x+2] = self.lazy[x]
            self.lazy[x] = self.e
        return str(self.lazy[self.size-1:self.size-1 + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.size = 1 << (self.n - 1).bit_length()
        self.lazy = [self.e] * (self.size << 1)

    def update(self, l, r, x):
        """
        半開区間 [l, r) の値を x に更新 （ 0-indexed ）　（ O(logN) ）
        """
        l += (self.size - 1)
        r += (self.size - 1)
        self.propagate(l)
        self.propagate(r-1)
        while l < r:
            if r&1 == 0:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = self.op(x, self.lazy[r])
            if l&1 == 0:
                self.lazy[l] = self.op(x, self.lazy[l])
                l += 1
            l = (l - 1) // 2
            r = (r - 1) // 2

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        tmp = []
        while i>0:
            i -= 1
            i >>= 1
            tmp.append(i)
        for x in reversed(tmp):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.op(self.lazy[x], self.lazy[2*x+1])
            self.lazy[2*x+2] = self.op(self.lazy[x], self.lazy[2*x+2])
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 0-indexed ） ( O(logN) )
        """
        i += (self.size - 1)
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(self.size-1):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.op(self.lazy[x], self.lazy[2*x+1])
            self.lazy[2*x+2] = self.op(self.lazy[x], self.lazy[2*x+2])
            self.lazy[x] = self.e
        for a in self.lazy[self.size-1:self.size-1+self.n]:
            yield a

    def __str__(self):
        for x in range(self.size-1):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.op(self.lazy[x], self.lazy[2*x+1])
            self.lazy[2*x+2] = self.op(self.lazy[x], self.lazy[2*x+2])
            self.lazy[x] = self.e
        return str(self.lazy[self.size-1:self.size-1 + self.n])

class ListList:
    """ tupleを一番目の添え字に関してソートする"""
    def __init__(self, max_value_list):
        """
        :param max_value_list: tuple = (i, j, k) を考えた時、  max_value_list = (j_max, k_max)
        """
        self.list_list = []
        self.separation = [0]
        self.max_value_list = list(map(lambda x: x.bit_length(), max_value_list))
        for a in self.max_value_list:
            self.separation.append(self.separation[-1] + a)
        self.separation.reverse()
        self.mask = list(map(lambda x: x-1, self.separation))

    def append(self, array):
        temp = 0
        for x, i in zip(array, self.separation):
            temp += x<<i
        self.list_list.append(temp)

    def sort(self, reverse=False):
        return self.list_list.sort(reverse=reverse)

    def __getitem__(self, item):
        temp = self.list_list[item]
        array = []
        for a in self.max_value_list:
            array = [temp&((1<<a)-1)] + array
            temp>>=a
        array = [temp] + array
        return array

    def __iter__(self):
        for i in range(len(self.list_list)):
            yield self[i]

    def __str__(self):
        text = []
        for a in self:
            text.append("[" + ", ".join(list(map(str, a))) + "]")
        return "[" + ", ".join(text) + "]"

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = ListList([10**9,10**9])
for _ in range(N):
    S, T, X = map(int, input().split())
    Qu.append((X, S, T))
Qu.sort(reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    X, S, T = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")

Submission status: Accepted

Solution code:
class DualSegmentTree():

    def __init__(self, n, op, e):
        """
        :param n: 配列の要素数
        :param op: 作用素（モノイド＝結合則＋単位元存在）
        :param e:  単位元
        """
        self.n = n
        self.op = op
        self.e = e
        self.size = 1 << (self.n - 1).bit_length()
        self.lazy = [self.e] * (self.size << 1)

    def update(self, l, r, x):
        """
        半開区間 [l, r) の値を x に更新 （ 0-indexed ）　（ O(logN) ）
        """
        l += (self.size - 1)
        r += (self.size - 1)
        self.propagate(l)
        self.propagate(r-1)
        while l < r:
            if r&1 == 0:
                r -= 1              # 半開区間なので先に引いてる
                self.lazy[r] = self.op(x, self.lazy[r])
            if l&1 == 0:
                self.lazy[l] = self.op(x, self.lazy[l])
                l += 1
            l = (l - 1) // 2
            r = (r - 1) // 2

    def propagate(self, i):
        """
        根から葉に伝搬させる。可換モノイドの場合は更新時の伝搬をサボれる。　（ O(logN) ）
        """
        tmp = []
        while i>0:
            i -= 1
            i >>= 1
            tmp.append(i)
        for x in reversed(tmp):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.op(self.lazy[x], self.lazy[2*x+1])
            self.lazy[2*x+2] = self.op(self.lazy[x], self.lazy[2*x+2])
            self.lazy[x] = self.e

    def get(self, i):
        """
        i 番目の値を取得（ 0-indexed ） ( O(logN) )
        """
        i += (self.size - 1)
        self.propagate(i)
        return self.lazy[i]

    def __getitem__(self, i):
        return self.get(i)

    def __iter__(self):
        for x in range(self.size-1):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.op(self.lazy[x], self.lazy[2*x+1])
            self.lazy[2*x+2] = self.op(self.lazy[x], self.lazy[2*x+2])
            self.lazy[x] = self.e
        for a in self.lazy[self.size-1:self.size-1+self.n]:
            yield a

    def __str__(self):
        for x in range(self.size-1):
            if self.lazy[x] == self.e:
                continue
            self.lazy[2*x+1] = self.op(self.lazy[x], self.lazy[2*x+1])
            self.lazy[2*x+2] = self.op(self.lazy[x], self.lazy[2*x+2])
            self.lazy[x] = self.e
        return str(self.lazy[self.size-1:self.size-1 + self.n])

##################################################################################################################
import sys
from bisect import *
input = sys.stdin.readline

N, Q = map(int, input().split())

e = -1
op = lambda x, y: x if x != e else y
st = DualSegmentTree(Q, op, e)

Qu = [list(map(int, input().split())) for _ in range(N)]
Qu.sort(key=lambda x:x[2], reverse=True)

D = [int(input()) for _ in range(Q)]

for q in Qu:
    S, T, X = q
    L = bisect_left(D,S-X)
    R = bisect_left(D,T-X)
    st.update(L, R, X)
print(*st, sep="\n")