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: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-

import sys
from collections import Counter, defaultdict

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

def bisearch_min(mn, mx, func):
    """ 条件を満たす最小値を見つける二分探索 """
    ok = mx
    ng = mn
    while ng+1 < ok:
        mid = (ok+ng) // 2
        if func(mid):
            # 下を探しに行く
            ok = mid
        else:
            # 上を探しに行く
            ng = mid
    return ok

class BIT:

    def __init__(self, n):
        # 0-indexed
        nv = 1
        while nv < n:
            nv *= 2
        self.size = nv
        self.tree = [0] * nv

    def sum(self, i):
        """ [0, i]を合計する """
        s = 0
        i += 1
        while i > 0:
            s += self.tree[i-1]
            i -= i & -i
        return s

    def add(self, i, x):
        """ 値の追加：添字i, 値x """
        i += 1
        while i <= self.size:
            self.tree[i-1] += x
            i += i & -i

    def get(self, l, r=None):
        """ 区間和の取得 [l, r) """
        # 引数が1つなら一点の値を取得
        if r is None: r = l + 1
        res = 0
        if r: res += self.sum(r-1)
        if l: res -= self.sum(l-1)
        return res

N, Q = MAP()
ST = set()
X = set()
A = defaultdict(list)
for i in range(N):
    s, t, x = MAP()
    # 全ての工事を同じ時系列に持ってくる
    ST.add(s-x)
    ST.add(t-x)
    X.add(x)
    A[s-x].append((x, 0))
    A[t-x].append((x, 1))
D = LIST(Q)

# 座標圧縮
zip_x, unzip_x = {}, {}
X = sorted(X)
for i in range(len(X)):
    zip_x[X[i]] = i
    unzip_x[i] = X[i]

def calc(m):
    cnt = bit.sum(m)
    return cnt > 0

S = sorted(ST|set(D))
B = {}
bit = BIT(len(X))
for key in S:
    li = A[key]
    for x, flag in li:
        if flag == 0:
            bit.add(zip_x[x], 1)
        else:
            bit.add(zip_x[x], -1)
    # BIT二分探索
    mn = bisearch_min(-1, len(X), calc)
    B[key] = unzip_x[mn] if mn != len(X) else -1
[print(B[x]) for x in D]

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-

import sys
from collections import Counter, defaultdict

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

N, Q = MAP()
STX = []
X = set()
A = defaultdict(list)
for i in range(N):
    s, t, x = MAP()
    # 全ての工事を同じ時系列に持ってくる
    STX.append((s-x, t-x, x))
    X.add(s-x)
    X.add(t-x)
    A[s-x].append((x, 0))
    A[t-x].append((x, 1))
D = LIST(Q)

S = sorted(X|set(D))
B = {}
C = Counter()
for key in S:
    li = A[key]
    for x, flag in li:
        if flag == 0:
            C[x] += 1
        else:
            C[x] -= 1
        if C[x] == 0:
            del C[x]
    mn = min(C) if len(C) else -1
    B[key] = mn
[print(B[x]) for x in D]

Submission status: Time Limit Exceeded

Solution code:
# https://atcoder.jp/contests/abc128/submissions/7097699
from bisect import bisect_left

n,q = map(int, input().split())
road = [list(map(int, input().split())) for i in range(n)]
road.sort(key=lambda x: x[2])
start = [int(input()) for i in range(q)]

skip = [-1]*q
ans = [-1]*q
for s,t,x in road:
    left = bisect_left(start, s-x)
    right = bisect_left(start, t-x)
    # [left, right)をxで埋める
    # すでに存在するところ(skipがあるところ)は飛ばす
    while left < right:
        if skip[left] == -1:
            ans[left] = x
            skip[left] = right
            left += 1
        else:
            left = skip[left]
print(*ans, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

class RangeUpdateQuery:
    def __init__(self, n):
        self.n0 = 2**(n-1).bit_length()
        self.INF = float("inf")
        self.data = [self.INF]*(2*self.n0-1)

    def update(self, l,r,v):
        l += self.n0
        r += self.n0
        while l < r:
            if r&1:
                r -= 1
                self.data[r-1] = v
            if l&1:
                self.data[l-1] = v
                l += 1
            l >>=1
            r >>=1

    def query(self, i):
        i += self.n0-1
        res = self.INF
        while i+1:
            if self.data[i] < res:
                res = self.data[i]
            i = ~-i//2
        return res

n,q = map(int, input().split())
start = [None]*q
se = set()

road = []
for i in range(n):
    s,t,x = map(int, input().split())
    se.add(x-s)
    se.add(x-(t-1))
    road.append([x, x-(t-1), x-s])
for i in range(q):
    d = int(input())
    start[i] = -d
    se.add(-d)

dd = sorted(se)
d = {j:i for i, j in enumerate(dd)}
k = len(d)

RUQ = RangeUpdateQuery(k)
road.sort(reverse=True)

for i, (x, s, t) in enumerate(road):
    l = d[s]
    r = d[t]
    RUQ.update(l, r+1, x)

ans = []
for i in range(q):
    x = RUQ.query(d[start[i]])
    if x == float("inf"):
        x = -1
    ans.append(x)

print(*ans, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

class RangeUpdateQuery:
    def __init__(self, n):
        self.n0 = 2**(n-1).bit_length()
        self.INF = (-1, -1)
        self.data = [self.INF]*(2*self.n0-1)

    def update(self, l,r,v):
        l += self.n0
        r += self.n0
        while l < r:
            if r&1:
                r -= 1
                self.data[r-1] = v
            if l&1:
                self.data[l-1] = v
                l += 1
            l >>=1
            r >>=1

    def query(self, i):
        i += self.n0-1
        res = self.INF
        while i+1:
            if self.data[i] > res:
                res = self.data[i]
            i = ~-i//2
        return res

n,q = map(int, input().split())
start = [None]*q
se = set()
road = []
for i in range(n):
    s,t,x = map(int, input().split())
    se.add(x-s)
    se.add(x-(t-1))
    road.append([x, x-(t-1), x-s])
for i in range(q):
    d = int(input())
    start[i] = -d
    se.add(-d)

dd = sorted(se)
d = {j:i for i, j in enumerate(dd)}
k = len(d)

RUQ = RangeUpdateQuery(k)
road.sort(reverse=True)

for i, (x, s, t) in enumerate(road):
    l = d[s]
    r = d[t]
    RUQ.update(l, r+1, (i, x))

ans = []
for i in range(q):
    _, x = RUQ.query(d[start[i]])
    ans.append(x)

print(*ans, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

class RangeUpdateQuery:
    def __init__(self, n):
        self.n0 = 2**(n-1).bit_length()
        self.INF = (-1, -1)
        self.data = [self.INF]*(2*self.n0-1)

    def update(self, l,r,v):
        l += self.n0
        r += self.n0
        while l < r:
            if r&1:
                r -= 1
                self.data[r-1] = v
            if l&1:
                self.data[l-1] = v
                l += 1
            l >>=1
            r >>=1

    def query(self, i):
        i += self.n0-1
        res = self.INF
        while i+1:
            if self.data[i] > res:
                res = self.data[i]
            i = ~-i//2
        return res

n,q = map(int, input().split())
start = [None]*q
se = set()
road = []
for i in range(n):
    s,t,x = map(int, input().split())
    se.add(x-s)
    se.add(x-(t-1))
    road.append([x, x-(t-1), x-s])
for i in range(q):
    d = int(input())
    start[i] = -d
    se.add(-d)

dd = sorted(se)
d = {j:i for i, j in enumerate(dd)}
k = len(d)

RUQ = RangeUpdateQuery(k)
road.sort(reverse=True)
for i, (x, s, t) in enumerate(road):
    l = d[s]
    r = d[t]
    RUQ.update(l, r+1, (i, x))

ans = []
for i in range(q):
    _, x = RUQ.query(d[start[i]])
    ans.append(x)

print(*ans, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N,num):
    if N<=0:
        for _ in range(num): return []
    elif num==1:
        return [I() for _ in range(N)]
    else:
        read_all = [tuple(II()) for _ in range(N)]
        return map(list,zip(*read_all))

#################

from operator import itemgetter
from bisect import bisect_left
from collections import defaultdict

#1-indexedの遅延評価セグメント木
class LazySegmentTree:
    def __init__(self,N,default=float('inf')):
        #演算の定義
        self.op = min
        #初期化の値
        self.default = default
        self.LV = (N-1).bit_length()
        self.N0 = 2**self.LV
        self.tree = defaultdict(lambda:default)
        self.lazy = defaultdict(lambda:None)
 
    #伝搬対象の区間を求める
    def gindex(self, l, r):
        L = (l + self.N0) >> 1; R = (r + self.N0) >> 1
        lc = 0 if l & 1 else (L & -L).bit_length()
        rc = 0 if r & 1 else (R & -R).bit_length()
        for i in range(self.LV):
            if rc <= i:
                yield R
            if L < R and lc <= i:
                yield L
            L >>= 1; R >>= 1
 
    #遅延伝搬処理
    def propagates(self,*ids):
        for i in reversed(ids):
            v = self.lazy[i-1]
            if v is None:
                continue
            self.lazy[2*i-1] = self.tree[2*i-1] = self.lazy[2*i] = self.tree[2*i] = v
            self.lazy[i-1] = None
 
    #区間[l,r)の値をxに更新
    def update(self,l,r,x):
        if l < r:
            *ids, = self.gindex(l, r)
            self.propagates(*ids)
 
            L = l + self.N0; R = r + self.N0
            while L < R:
                if R & 1:
                    R -= 1
                    self.lazy[R-1] = self.tree[R-1] = x
                if L & 1:
                    self.lazy[L-1] = self.tree[L-1] = x
                    L += 1
                L >>= 1; R >>= 1
 
            for i in ids:
                self.tree[i-1] = self.op(self.tree[2*i-1], self.tree[2*i])
 
    #区間[l,r)へのクエリ
    def query(self,l,r):
        self.propagates(*self.gindex(l, r))
        L = l + self.N0; R = r + self.N0
        s = self.default
        while L < R:
            if R & 1:
                R -= 1
                s = self.op(s,self.tree[R-1])
            if L & 1:
                s = self.op(s,self.tree[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s
 
    #1-indexedでk番目の値を取得
    def get(self,k):
        self.propagates(*self.gindex(k, k+1))
        return self.tree[k+self.N0-1]
      
N,Q = II()
a = []
for _ in range(N):
    s,t,x = II()
    a.append((x, s-x-0.5, t-x-0.5))
D = Line(Q,1)
 
a.sort(key=itemgetter(0),reverse=True)
 
seg = LazySegmentTree(Q, 10**9+1)
for b in a:
    l = bisect_left(D,b[1]) + 1
    r = bisect_left(D,b[2]) + 1
    seg.update(l,r,b[0])
    
for i in range(Q):
    x = seg.get(i+1)
    if x == 10**9+1:
        print(-1)
    else:
        print(x)

Submission status: Time Limit Exceeded

Solution code:
N, Q = map(int,input().split(' '))
Gt=[]
Gx=[]
for i in range(N):
    S,T,X = map(int,input().split(' '))
    Gt.append([S-X,T-X])
    Gx.append(X)

#print(Gt,Gx)
def GuardTime(d,Gt,Gx):
    minGx=-1
    for i in range(len(Gt)):
        #print(i,Gt,d)
        if Gt[i][0] <= d and d < Gt[i][1]:
            if minGx==-1:
                minGx=Gx[i]
            else:
                minGx=min(Gx[i],minGx)
    return(minGx) 

for i in range(Q):
    D = int(input())
    print(GuardTime(D,Gt,Gx))

Submission status: Time Limit Exceeded

Solution code:
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N,num):
    if N<=0:
        for _ in range(num): return []
    elif num==1:
        return [I() for _ in range(N)]
    else:
        read_all = [tuple(map(int, input().split())) for _ in range(N)]
        return map(list,zip(*read_all))

#################

from operator import itemgetter
from bisect import bisect_left

#1-indexedの遅延評価セグメント木
class LazySegmentTree:
    def __init__(self,N,default=float('inf')):
        #演算の定義
        self.op = min
        #初期化の値
        self.default = default
        self.LV = (N-1).bit_length()
        self.N0 = 2**self.LV
        self.tree = [self.default]*(2*self.N0)
        self.lazy = [None]*(2*self.N0)

    #伝搬対象の区間を求める
    def gindex(self, l, r):
        L = (l + self.N0) >> 1; R = (r + self.N0) >> 1
        lc = 0 if l & 1 else (L & -L).bit_length()
        rc = 0 if r & 1 else (R & -R).bit_length()
        for i in range(self.LV):
            if rc <= i:
                yield R
            if L < R and lc <= i:
                yield L
            L >>= 1; R >>= 1

    #遅延伝搬処理
    def propagates(self,*ids):
        for i in reversed(ids):
            v = self.lazy[i-1]
            if v is None:
                continue
            self.lazy[2*i-1] = self.tree[2*i-1] = self.lazy[2*i] = self.tree[2*i] = v
            self.lazy[i-1] = None

    #区間[l,r)の値をxに更新
    def update(self,l,r,x):
        if l < r:
            *ids, = self.gindex(l, r)
            self.propagates(*ids)

            L = l + self.N0; R = r + self.N0
            while L < R:
                if R & 1:
                    R -= 1
                    self.lazy[R-1] = self.tree[R-1] = x
                if L & 1:
                    self.lazy[L-1] = self.tree[L-1] = x
                    L += 1
                L >>= 1; R >>= 1

            #for i in ids:
            #    self.tree[i-1] = self.op(self.tree[2*i-1], self.tree[2*i])

    #区間[l,r)へのクエリ
    def query(self,l,r):
        self.propagates(*self.gindex(l, r))
        L = l + self.N0; R = r + self.N0
        s = self.default
        while L < R:
            if R & 1:
                R -= 1
                s = self.op(s,self.tree[R-1])
            if L & 1:
                s = self.op(s,self.tree[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s

    #1-indexedでk番目の値を取得
    def get(self,k):
        self.propagates(*self.gindex(k, k+1))
        return self.tree[k+self.N0-1]

N,Q = II()
a = []
for _ in range(N):
    s,t,x = II()
    a.append((x, s-x-0.5, t-x-0.5))
D = Line(Q,1)

a.sort(key=itemgetter(0),reverse=True)

seg = LazySegmentTree(Q, 10**9+1)
for b in a:
    l = bisect_left(D,b[1]) + 1
    r = bisect_left(D,b[2]) + 1
    seg.update(l,r,b[0])

for i in range(Q):
    x = seg.get(i+1)
    if x == 10**9+1:
        print(-1)
    else:
        print(x)

Submission status: Time Limit Exceeded

Solution code:
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N,num):
    if N<=0:
        for _ in range(num): return []
    elif num==1:
        return [I() for _ in range(N)]
    else:
        read_all = [tuple(map(int, input().split())) for _ in range(N)]
        return map(list,zip(*read_all))

#################

from operator import itemgetter
from bisect import bisect_left

#1-indexedの遅延評価セグメント木
class LazySegmentTree:
    def __init__(self,N,default=float('inf')):
        #演算の定義
        self.op = min
        #初期化の値
        self.default = default
        self.LV = (N-1).bit_length()
        self.N0 = 2**self.LV
        self.tree = [self.default]*(2*self.N0)
        self.lazy = [None]*(2*self.N0)

    #伝搬対象の区間を求める
    def gindex(self, l, r):
        L = (l + self.N0) >> 1; R = (r + self.N0) >> 1
        lc = 0 if l & 1 else (L & -L).bit_length()
        rc = 0 if r & 1 else (R & -R).bit_length()
        for i in range(self.LV):
            if rc <= i:
                yield R
            if L < R and lc <= i:
                yield L
            L >>= 1; R >>= 1

    #遅延伝搬処理
    def propagates(self,*ids):
        for i in reversed(ids):
            v = self.lazy[i-1]
            if v is None:
                continue
            self.lazy[2*i-1] = self.tree[2*i-1] = self.lazy[2*i] = self.tree[2*i] = v
            self.lazy[i-1] = None

    #区間[l,r)の値をxに更新
    def update(self,l,r,x):
        if l < r:
            *ids, = self.gindex(l, r)
            self.propagates(*ids)

            L = l + self.N0; R = r + self.N0
            while L < R:
                if R & 1:
                    R -= 1
                    self.lazy[R-1] = self.tree[R-1] = x
                if L & 1:
                    self.lazy[L-1] = self.tree[L-1] = x
                    L += 1
                L >>= 1; R >>= 1

            for i in ids:
                self.tree[i-1] = self.op(self.tree[2*i-1], self.tree[2*i])

    #区間[l,r)へのクエリ
    def query(self,l,r):
        self.propagates(*self.gindex(l, r))
        L = l + self.N0; R = r + self.N0
        s = self.default
        while L < R:
            if R & 1:
                R -= 1
                s = self.op(s,self.tree[R-1])
            if L & 1:
                s = self.op(s,self.tree[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s

    #1-indexedでk番目の値を取得
    def get(self,k):
        self.propagates(*self.gindex(k, k+1))
        return self.tree[k+self.N0-1]

N,Q = II()
a = []
for _ in range(N):
    s,t,x = II()
    a.append((x, s-x-0.5, t-x-0.5))
D = Line(Q,1)

a.sort(key=itemgetter(0),reverse=True)

seg = LazySegmentTree(Q, 10**9+1)
for b in a:
    l = bisect_left(D,b[1]) + 1
    r = bisect_left(D,b[2]) + 1
    seg.update(l,r,b[0])

for i in range(Q):
    x = seg.get(i+1)
    if x == 10**9+1:
        print(-1)
    else:
        print(x)

Submission status: Time Limit Exceeded

Solution code:
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N,num):
    if N<=0:
        for _ in range(num): return []
    elif num==1:
        return [I() for _ in range(N)]
    else:
        read_all = [tuple(map(int, input().split())) for _ in range(N)]
        return map(list,zip(*read_all))

#################

from operator import itemgetter
from bisect import bisect_left

class LazySegmentTree:
    def __init__(self,N,default=float('inf')):
        #演算の定義
        self.op = min
        #初期化の値
        self.default = default
        self.LV = (N-1).bit_length()
        self.N0 = 2**self.LV
        self.tree = [self.default]*(2*self.N0)
        self.lazy = [None]*(2*self.N0)

    #伝搬対象の区間を求める
    def gindex(self, l, r):
        L = (l + self.N0) >> 1; R = (r + self.N0) >> 1
        lc = 0 if l & 1 else (L & -L).bit_length()
        rc = 0 if r & 1 else (R & -R).bit_length()
        for i in range(self.LV):
            if rc <= i:
                yield R
            if L < R and lc <= i:
                yield L
            L >>= 1; R >>= 1

    #遅延伝搬処理
    def propagates(self,*ids):
        for i in reversed(ids):
            v = self.lazy[i-1]
            if v is None:
                continue
            self.lazy[2*i-1] = self.tree[2*i-1] = self.lazy[2*i] = self.tree[2*i] = v
            self.lazy[i-1] = None

    #区間[l,r)の値をxに更新
    def update(self,l,r,x):
        if l < r:
            *ids, = self.gindex(l, r)
            self.propagates(*ids)

            L = l + self.N0; R = r + self.N0
            while L < R:
                if R & 1:
                    R -= 1
                    self.lazy[R-1] = self.tree[R-1] = x
                if L & 1:
                    self.lazy[L-1] = self.tree[L-1] = x
                    L += 1
                L >>= 1; R >>= 1

            for i in ids:
                self.tree[i-1] = self.op(self.tree[2*i-1], self.tree[2*i])

    #区間[l,r)へのクエリ
    def query(self,l,r):
        self.propagates(*self.gindex(l, r))
        L = l + self.N0; R = r + self.N0
        s = self.default
        while L < R:
            if R & 1:
                R -= 1
                s = self.op(s,self.tree[R-1])
            if L & 1:
                s = self.op(s,self.tree[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s

N,Q = II()
a = []
for _ in range(N):
    s,t,x = II()
    a.append((x, s-x-0.5, t-x-0.5))
D = Line(Q,1)

a.sort(key=itemgetter(0),reverse=True)

seg = LazySegmentTree(Q, 10**9+1)
for b in a:
    l = bisect_left(D,b[1]) + 1
    r = bisect_left(D,b[2]) + 1
    seg.update(l,r,b[0])

for i in range(Q):
    x = seg.query(i+1,i+2)
    if x == 10**9+1:
        print(-1)
    else:
        print(x)

Submission status: Time Limit Exceeded

Solution code:
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N,num):
    if N<=0:
        for _ in range(num): return []
    elif num==1:
        return [I() for _ in range(N)]
    else:
        read_all = [tuple(map(int, input().split())) for _ in range(N)]
        return map(list,zip(*read_all))

#################

from operator import itemgetter
from bisect import bisect_left

class LazySegmentTree:
    def __init__(self,N,default=float('inf')):
        #演算の定義
        self.op = min
        #初期化の値
        self.default = default
        self.N0 = 2**(N-1).bit_length()
        self.tree = [self.default]*(2*self.N0)
        self.lazy = [None]*(2*self.N0)

    #伝搬される区間のインデックス(1-indexed)を全て列挙するgenerator
    def gindex(self,l,r):
        L = l + self.N0; R = r + self.N0
        lm = (L // (L & -L)) >> 1
        rm = (R // (R & -R)) >> 1
        while L < R:
            if R <= rm:
                yield R
            if L <= lm:
                yield L
            L >>= 1; R >>= 1
        while L:
            yield L
            L >>= 1

    #1-indexedで単調増加のインデックスリストを渡す
    def propagates(self,*ids):
        for i in reversed(ids):
            v = self.lazy[i-1]
            if v is None:
                continue
            self.lazy[2*i-1] = self.tree[2*i-1] = self.lazy[2*i] = self.tree[2*i] = v
            self.lazy[i-1] = None

    #区間[l,r)の値をxに更新
    def update(self,l,r,x):
        if l < r:
            *ids, = self.gindex(l, r)
            self.propagates(*ids)

            L = l + self.N0; R = r + self.N0
            while L < R:
                if R & 1:
                    R -= 1
                    self.lazy[R-1] = self.tree[R-1] = x
                if L & 1:
                    self.lazy[L-1] = self.tree[L-1] = x
                    L += 1
                L >>= 1; R >>= 1

            for i in ids:
                self.tree[i-1] = self.op(self.tree[2*i-1], self.tree[2*i])

    #区間[l,r)へのクエリ
    def query(self,l,r):
        self.propagates(*self.gindex(l, r))
        L = l + self.N0; R = r + self.N0
        s = self.default
        while L < R:
            if R & 1:
                R -= 1
                s = self.op(s,self.tree[R-1])
            if L & 1:
                s = self.op(s,self.tree[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s

N,Q = II()
a = []
for _ in range(N):
    s,t,x = II()
    a.append((x, s-x-0.5, t-x-0.5))
D = Line(Q,1)

a.sort(key=itemgetter(0),reverse=True)

seg = LazySegmentTree(Q, 10**9+1)
for b in a:
    l = bisect_left(D,b[1]) + 1
    r = bisect_left(D,b[2]) + 1
    seg.update(l,r,b[0])

for i in range(Q):
    x = seg.query(i+1,i+2)
    if x == 10**9+1:
        print(-1)
    else:
        print(x)

Submission status: Time Limit Exceeded

Solution code:
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N,num):
    if N<=0:
        for _ in range(num): return []
    elif num==1:
        return [I() for _ in range(N)]
    else:
        read_all = [tuple(map(int, input().split())) for _ in range(N)]
        return map(list,zip(*read_all))

#################

from operator import itemgetter
from bisect import bisect_left

class LazySegmentTree:
    def __init__(self,N,default=float('inf')):
        #演算の定義
        self.op = min
        #初期化の値
        self.default = default
        self.N0 = 2**(N-1).bit_length()
        self.tree = [self.default]*(2*self.N0)
        self.lazy = [None]*(2*self.N0)

    #伝搬される区間のインデックス(1-indexed)を全て列挙するgenerator
    def gindex(self,l,r):
        L = l + self.N0; R = r + self.N0
        lm = (L // (L & -L)) >> 1
        rm = (R // (R & -R)) >> 1
        while L < R:
            if R <= rm:
                yield R
            if L <= lm:
                yield L
            L >>= 1; R >>= 1
        while L:
            yield L
            L >>= 1

    #1-indexedで単調増加のインデックスリストを渡す
    def propagates(self,*ids):
        for i in reversed(ids):
            v = self.lazy[i-1]
            if v is None:
                continue
            self.lazy[2*i-1] = self.tree[2*i-1] = self.lazy[2*i] = self.tree[2*i] = v
            self.lazy[i-1] = None

    #区間[l,r)の値をxに更新
    def update(self,l,r,x):
        if l < r:
            *ids, = self.gindex(l, r)
            self.propagates(*ids)

            L = l + self.N0; R = r + self.N0
            while L < R:
                if R & 1:
                    R -= 1
                    self.lazy[R-1] = self.tree[R-1] = x
                if L & 1:
                    self.lazy[L-1] = self.tree[L-1] = x
                    L += 1
                L >>= 1; R >>= 1

            for i in ids:
                self.tree[i-1] = self.op(self.tree[2*i-1], self.tree[2*i])

    #区間[l,r)へのクエリ
    def query(self,l,r):
        self.propagates(*self.gindex(l, r))
        L = l + self.N0; R = r + self.N0
        s = self.default
        while L < R:
            if R & 1:
                R -= 1
                s = self.op(s,self.tree[R-1])
            if L & 1:
                s = self.op(s,self.tree[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s

N,Q = II()
a = []
for _ in range(N):
    s,t,x = II()
    a.append((x, s-x-0.5, t-x-0.5))
D = Line(Q,1)
D = tuple(D)

a.sort(key=itemgetter(0),reverse=True)

seg = LazySegmentTree(Q, 10**9+1)
for i in range(N):
    l = bisect_left(D,a[i][1]) + 1
    r = bisect_left(D,a[i][2]) + 1
    seg.update(l,r,a[i][0])

for i in range(Q):
    x = seg.query(i+1,i+2)
    if x == 10**9+1:
        print(-1)
    else:
        print(x)