Problem:


Score : 600 points

Problem Statement

We have N points numbered 1 to N arranged in a line in this order.

Takahashi decides to make an undirected graph, using these points as the vertices.
In the beginning, the graph has no edge. Takahashi will do M operations to add edges in this graph.
The i-th operation is as follows:

The operation uses integers L_i and R_i between 1 and N (inclusive), and a positive integer C_i. For every pair of integers (s, t) such that L_i \leq s < t \leq R_i, add an edge of length C_i between Vertex s and Vertex t.

The integers L_1, ..., L_M, R_1, ..., R_M, C_1, ..., C_M are all given as input.

Takahashi wants to solve the shortest path problem in the final graph obtained. Find the length of the shortest path from Vertex 1 to Vertex N in the final graph.

Constraints

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq L_i < R_i \leq N

1 \leq C_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N M
L_1 R_1 C_1
:
L_M R_M C_M

Output

Print the length of the shortest path from Vertex 1 to Vertex N in the final graph.
If there is no shortest path, print -1 instead.

Sample Input 1

4 3
1 3 2
2 4 3
1 4 6

Sample Output 1

5

We have an edge of length 2 between Vertex 1 and Vertex 2, and an edge of length 3 between Vertex 2 and Vertex 4, so there is a path of length 5 between Vertex 1 and Vertex 4.

Sample Input 2

4 2
1 2 1
3 4 2

Sample Output 2

-1

Sample Input 3

10 7
1 5 18
3 4 8
1 3 5
4 7 10
5 9 8
6 10 5
8 10 3

Sample Output 3

28



Sample input:
4 3
1 3 2
2 4 3
1 4 6


Sample output:
5

Submission status: Accepted

Solution code:
from heapq import heappush, heappop
def dijkstra(s,n,dic):
  q = [(0,s)]
  dist = [10**20]*n
  dist[s] = 0
  while q:
    v,p = heappop(q)
    if dist[p]<v:
      continue
    for e,c in dic[p]:
      if dist[e]>dist[p]+c:
        dist[e] = dist[p]+c
        heappush(q,(dist[e],e))
  return dist
N, M, *L = map(int, open(0).read().split())
Els = [[] for i in range(N+1)]
for i in range(2,N+1):
  Els[i].append((i-1,0))
for l,r,c in zip(*[iter(L)]*3):
  Els[l].append((r,c))
  
dist = dijkstra(1,N+1,Els)
if dist[N]==10**20:
  print(-1)
else:
  print(dist[N])

Submission status: Accepted

Solution code:
N,M=map(int,input().split())
LRC=sorted([list(map(int,input().split())) for i in range(M)],key=lambda x:x[0])
class rmq:
    def __init__(self,N):
        self.N0=2**(N-1).bit_length()
        self.INF=2**63-1
        self.data=[self.INF]*(2*self.N0)
        self.lazy=[None]*(2*self.N0)
    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
    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.data[2*i-1] = self.lazy[2*i] = self.data[2*i] = v
            self.lazy[i-1] = None
    def update(self,l, r, x):
        *ids, = self.gindex(l, r)
        self.propagates(*ids)
        L = self.N0 + l; R = self.N0 + r
        while L < R:
            if R & 1:
                R -= 1
                self.lazy[R-1] = self.data[R-1] = x
            if L & 1:
                self.lazy[L-1] = self.data[L-1] = x
                L += 1
            L >>= 1; R >>= 1
        for i in ids:
            self.data[i-1] = min(self.data[2*i-1], self.data[2*i])
    def rmin(self,l, r):
        self.propagates(*self.gindex(l, r))
        L = self.N0 + l; R = self.N0 + r
        s = self.INF
        while L < R:
            if R & 1:
                R -= 1
                s = min(s, self.data[R-1])
            if L & 1:
                s = min(s, self.data[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s
d=rmq(N)
d.update(0,1,0)
for l,r,c in LRC:
    d.update(r-1,r,min(d.data[d.N0+r-2],d.rmin(l-1,r-1)+c))
a=d.rmin(N-1,N)
print(a if a<d.INF else -1)

Submission status: Accepted

Solution code:
class Dijkstra():
  class Edge():
    # weighted directed edge
    def __init__(self,_to,_cost):
      self.to=_to
      self.cost=_cost
  def __init__(self,V):
    # 0-indexed
    self.G=[[] for i in range(V)]
    self._E=0
    self._V=V
  def E(self):
    # number of edge
    return self._E
  def V(self):
    # number of vertex
    return self._V
  def add(self, _from, _to, _cost):
    # add vertex and edge cost
    self.G[_from].append(self.Edge(_to, _cost))
    self._E+=1
  def shortest_path(self,s):
    # return the list of shortest pathes from s to each vertex
    import heapq
    que=[]
    d=[float('inf')]*self._V
    d[s]=0
    heapq.heappush(que,(0,s))
    while que:
      cost,v=heapq.heappop(que)
      if d[v]<cost:continue
      for i in range(len(self.G[v])):
        e=self.G[v][i]
        if d[e.to]>d[v]+e.cost:
          d[e.to]=d[v]+e.cost
          heapq.heappush(que,(d[e.to],e.to))
    return d

n,m=map(int,input().split())
g=Dijkstra(n)
for i in range(1,n):
  g.add(i,i-1,0)
for i in range(m):
  u,v,c=map(int,input().split())
  if u>v:
    u,v=v,u
  g.add(u-1,v-1,c)
tmp=g.shortest_path(0)[-1]
if tmp==float('inf'):
  print(-1)
else:
  print(tmp)

Submission status: Accepted

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

import heapq

def dijkstra(start, edge):
    n = len(edge)
    dist = [float("inf")]*n
    dist[start] = 0
    que = [(0, start)]
    while que:
        d, v = heapq.heappop(que)
        if dist[v] < d:
            continue
        for nv, nd in edge[v]:
            if dist[nv] > d + nd:
                dist[nv] = d + nd
                heapq.heappush(que, (dist[nv], nv))
    return dist
  
n, m = map(int, input().split())
G = [[] for _ in range(n)]
for i in range(1, n):
  G[i].append((i-1, 0))
for _ in range(m):
  l, r, c = map(int, input().split())
  G[l-1].append((r-1, c))

D = dijkstra(0, G)
ans = D[n-1]
if ans == float("inf"):
  ans = -1
print(ans)

Submission status: Accepted

Solution code:
from heapq import heappop, heappush

n, m = map(int, input().split())

g = [[] for __ in range(n)]

for _ in range(m):
    l, r, c = map(int, input().split())
    g[l-1].append((r-1, c))

for i in range(1, n):
    g[i].append((i-1, 0))


d = [10**18] * n
d[0] = 0
q = [(0, 0)]
while q:
    dist_u, u = heappop(q)
    if d[u] < dist_u:
        continue
    for v, c in g[u]:
        if d[v] > dist_u + c:
            d[v] = dist_u + c
            heappush(q, (d[v], v))


print(d[n-1] if d[n-1] != 10**18 else -1)

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
n,m = map(int,input().split())
abd = [list(map(int,input().split())) for i in range(m)]
graph = [[] for i in range(n+1)]
for a,b,d in abd:
  graph[a].append((b,d))
for i in range(1,n):
  graph[i+1].append((i,0))
import heapq as hq
dist = [10**18]*(n+1)
dist[1] = 0
q = [(0,1)]
hq.heapify(q)
while q:
  d,x = hq.heappop(q)
  for y,dd in graph[x]:
    if dist[y] > dist[x]+dd:
      dist[y] = dist[x]+dd
      hq.heappush(q,(dist[y],y))
if dist[n] == 10**18:
  print(-1)
else:
  print(dist[n])

Submission status: Accepted

Solution code:
n,m = map(int,input().split())
abd = [list(map(int,input().split())) for i in range(m)]
graph = [[] for i in range(n+1)]
for a,b,d in abd:
  graph[a].append((b,d))
for i in range(1,n):
  graph[i+1].append((i,0))
import heapq as hq
dist = [10**18]*(n+1)
dist[1] = 0
q = [(0,1)]
hq.heapify(q)
while q:
  d,x = hq.heappop(q)
  for y,dd in graph[x]:
    if dist[y] > dist[x]+dd:
      dist[y] = dist[x]+dd
      hq.heappush(q,(dist[y],y))
if dist[n] == 10**18:
  print(-1)
else:
  print(dist[n])

Submission status: Accepted

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

def main():
    N,M = map(int,input().split())
    INF = 10**15
    root = [[] for _ in range(N)]
    for i in range(N-1):
        root[i+1].append((0,i))
    for _ in range(M):
        l,r,c = map(int,input().split())
        root[l-1].append((c,r-1))
    
    dist = [INF for _ in range(N)]
    q = [(0,0)]
    dist[0] = 0
    while q:
        d,now = heapq.heappop(q)
        if dist[now] < d:
            continue
        for cost,fol in root[now]:
            _d = d+cost
            if dist[fol] > _d:
                dist[fol] = _d
                heapq.heappush(q,(_d,fol))

    if dist[-1] == INF:
        print(-1)
    else:
        print(dist[-1])

if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
from heapq import heappush, heappop

def dijkstra(edges, size, source):
    # edge=探索するグラフ
    # size=グラフの点の数
    # source=スタート点
    distance = [float('inf')] * size
    distance[source] = 0
    visited = [False] * size
    pq = []
    heappush(pq, (0, source))
    while pq:
        dist_v, v = heappop(pq)
        visited[v] = True
        for u, weight in edges[v]:
            if not visited[u]:
                new_dist = dist_v + weight
                if distance[u] > new_dist:
                    distance[u] = new_dist
                    heappush(pq, (new_dist, u))
    return distance[n-1]

n,m = map(int, input().split())
a = [list(map(int, input().split())) for i in range(m)]
b = [[] for i in range(n)]

for i in range(m):
    b[a[i][0]-1].append((a[i][1]-1,a[i][2]))

# 戻るルートをコストゼロで追加
for i in range(n-1):
    b[i+1].append((i,0))

x=dijkstra(b,n,0)

if x==float('inf'):
    print(-1)

else:
    print(x)

Submission status: Accepted

Solution code:
import sys
from heapq import heapify, heappop, heappush

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

def dijkstra(start):
    dist = [INF] * (N+1)
    dist[start] = 0
    que = [(0, start)]
    while que:
        d, prev = heappop(que)
        if dist[prev] < d:
            continue
        for cost, next in graph[prev]:
            d1 = d + cost
            if dist[next] > d1:
                dist[next] = d1
                heappush(que, (d1, next))
    return dist

N, M = lr()
INF = 10 ** 15
graph = [[] for _ in range(N+1)] # 1-indexed
for i in range(2, N+1):
    graph[i].append((0, i-1))

for _ in range(M):
    l, r, c = lr()
    graph[l].append((c, r))

dist = dijkstra(1)

if dist[N] == INF:
    print(-1)
else:
    print(dist[N])
# 19

Submission status: Accepted

Solution code:
INFTY = 10**14+5
N,M = map(int,input().split())
A = sorted([list(map(int,input().split())) for _ in range(M)],key=lambda x:x[1])
A = sorted(A,key=lambda x:x[0])
d = [INFTY for _ in range(N+1)]
d[1] = 0
for i in range(M):
    L,R,C = A[i]
    d[R] = min(d[R],d[L]+C)
    j = R-1
    while d[j]>d[R]:
        d[j] = d[R]
        j -= 1
if d[N]>=INFTY:
    print(-1)
else:
    print(d[N])

Submission status: Accepted

Solution code:
import heapq


def dijkstra(g: list, start, goal=None):
    num = len(g)          # グラフのノード数
    dist = [float('inf') for i in range(num)]

    dist[start] = 0
    # プライオリティキュー．各要素は，(startからある頂点vまでの仮の距離, 頂点vのID)からなるタプル
    q = []
    heapq.heappush(q, (0, start))  # 始点をpush

    while q:
        prov_cost, src = heapq.heappop(q)  # pop
        # プライオリティキューに格納されている最短距離が，現在計算できている最短距離より大きければ，distの更新をする必要はない
        if dist[src] < prov_cost:
            continue
        # 他の頂点の探索
        for node, cost in g[src]:
            if dist[node] > dist[src] + cost:
                dist[node] = dist[src] + cost
                heapq.heappush(q, (dist[node], node))
    return dist


n, m = map(int, input().split())
g = [[] for _ in range(n)]
for i in range(n - 1):
    g[i + 1].append((i, 0))
for i in range(m):
    l, r, c = map(int, input().split())
    g[l - 1].append((r - 1, c))
d = dijkstra(g, 0)
if d[n - 1] == float('inf'):
    print(-1)
else:
    print(d[n - 1])

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
import heapq as hp

N, M = map(int, input().split())
graph = [[] for _ in range(N)]
for _ in range(M):
    l, r, c = map(int, input().split())
    graph[l-1].append((c, r-1))

for i in range(N-1):
    graph[i+1].append((0, i))

INF = 10**16
D = [INF for _ in range(N)] # 頂点iへの最短距離がD[i]
D[0] = 0 
q = [] # しまっていく優先度付きキュー
hp.heappush(q, (0, 0))

while q:
    nd, np = hp.heappop(q) # 一番距離が近いものを取ってくる
    if D[np] < nd: # 追加した後の残骸は見ない
        continue
    for d, p in graph[np]:
        if D[p] > D[np] + d: # 隣接するやつの中で今よりも近くなれるなら更新
            D[p] = D[np] + d
            hp.heappush(q, (D[p], p))

d = D[-1]
if d == INF:
    print(-1)
else:
    print(d)

Submission status: Accepted

Solution code:
def examA():
    N = I()
    ans = (N-1)//2
    print(ans)
    return

def examB():
    N = I()
    D = LI()
    d = Counter(D)
    loop = max(d.keys())
    if D[0]!=0 or d[0]!=1:
        print(0)
        return
#    print(d,loop)
    ans = 1; cur = 1
    for i in range(loop+1):
        if d[i]==0:
            print(0)
            return
        for _ in range(d[i]):
            ans *= cur
            ans %= mod2
        cur = d[i]
    print(ans)
    return

def examC():
    ans = 0
    print(ans)
    return

def examD():
    class Dijkstra(object):
        """
        construct: O(ElogV)
        """

        def __init__(self, edges, start=0):
            """
            :param list of list of list of int edges:
            :param int start=0:
            """
            self.__dist = [inf] * len(edges)
            self.__dist[start] = 0
            self.__calculate(edges, start)

        @property
        def dist(self):
            return self.__dist

        def __calculate(self, edges, start):
            Q = [(0, start)]  # (dist,vertex)
            while (Q):
                dist, v = heapq.heappop(Q)
                if self.dist[v] < dist: continue  # 候補として挙がったd,vだが、他に短いのがある
                for u, cost in edges[v]:
                    if self.dist[u] > self.dist[v] + cost:
                        self.__dist[u] = self.dist[v] + cost
                        heapq.heappush(Q, (self.dist[u], u))
    N, M = LI()
    V = [[]for _ in range(N)]
    for _ in range(M):
        l, r, c = LI()
        l -=1; r -=1
        V[l].append((r,c))
    for i in range(N-1):
        V[i+1].append((i,0))
#    print(V)
    D = Dijkstra(V)
    ans = D.dist[N-1]
    if ans==inf:
        ans = -1
    print(ans)
    return

def examE():
    ans = 0
    print(ans)
    return

def examF():
    ans = 0
    print(ans)
    return

import sys,copy,bisect,itertools,heapq,math
from heapq import heappop,heappush,heapify
from collections import Counter,defaultdict,deque
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))
def LFI(): return list(map(float,sys.stdin.readline().split()))
def LSI(): return list(map(str,sys.stdin.readline().split()))
def LS(): return sys.stdin.readline().split()
def SI(): return sys.stdin.readline().strip()
global mod,mod2,inf,alphabet
mod = 10**9 + 7
mod2 = 998244353
inf = 10**18
alphabet = [chr(ord('a') + i) for i in range(26)]

if __name__ == '__main__':
    examD()

"""

"""

Submission status: Accepted

Solution code:
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,copy,functools
import time,random

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 10**9+7
mod2 = 998244353
dd = [(-1,0),(0,1),(1,0),(0,-1)]
ddn = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(): return [list(map(int, l.split())) for l in sys.stdin.readlines()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)
def pe(s): return print(str(s), file=sys.stderr)
def JA(a, sep): return sep.join(map(str, a))
def JAA(a, s, t): return s.join(t.join(map(str, b)) for b in a)


def main():
    n,m = LI()
    lrc = sorted([LI() for _ in range(m)], key=lambda x: (x[0],x[2],-x[1]))
    lrc.append([inf,inf,inf])
    i = 0
    q = [(1,0),(inf,inf)]
    for l in range(1,n):
        while lrc[i][0] < l:
            i += 1
        while lrc[i][0] == l:
            _,r,c = lrc[i]
            i += 1
            qi = bisect.bisect_left(q, (l,-1))
            _, cc = q[qi]
            t = (r, cc+c)
            ti = bisect.bisect_left(q, t)
            if q[ti][1] > t[1] and q[ti-1][0] < r:
                if q[ti][0] == r:
                    q[ti] = t
                else:
                    q.insert(ti, t)
                while q[ti-1][1] > t[1]:
                    del q[ti-1]
                    ti -= 1

    t = q[-2]
    if t[0] < n:
        return -1

    return t[1]


print(main())

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
import heapq
def main():
    N, M = map( int, input().split())
    d = dict()
    E = [[] for _ in range(N)]
    for i in range(N-1):
        E[i+1].append((0,i))
    for _ in range(M):
        l, r, c = map( int, input().split())
        l -= 1
        r -= 1
        E[l].append((c,r))
    q = [(0,0)]
    heapq.heapify(q)
    path = [-1]*N
    while q:
        c, v = heapq.heappop(q)
        if path[v] >= 0:
            continue
        path[v] = c
        for cost, e in E[v]:
            if path[e] == -1:
                heapq.heappush(q, (c+cost, e))
    print(path[-1])
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
import heapq
def main():
    N, M = map( int, input().split())
    d = dict()
    E = [[] for _ in range(N)]
    for i in range(N-1):
        E[i+1].append((0,i))
    for _ in range(M):
        l, r, c = map( int, input().split())
        l -= 1
        r -= 1
        E[l].append((c,r))
    q = [(0,0)]
    heapq.heapify(q)
    path = [10**17]*N
    path[0] = 0
    while q:
        _, v = heapq.heappop(q)
        for cost, e in E[v]:
            if path[e] > path[v] + cost:
                path[e] = path[v] + cost
                heapq.heappush(q, (path[e], e))
    if path[N-1] == 10**17:
        print(-1)
    else:
        print(path[N-1])
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
from heapq import heappush,heappop
N,M=map(int,input().split())
LRC=[list(map(int,input().split())) for i in range(M)]
data=[[],[]]+[[[i-1,0]] for i in range(2,N+1)]
for L,R,C in LRC:
    data[L].append([R,C])
dist=[[0,1]]
inf=float("inf")
flag=[inf]*(N+1)
while dist:
    y,x=heappop(dist)
    if flag[x]!=inf:
        continue
    flag[x]=y
    for u in data[x]:
        if flag[u[0]]==inf:
            heappush(dist,[y+u[1],u[0]])
    if flag[N]!=inf:
        break
if flag[N]==inf:
    print(-1)
else:
    print(flag[N])

Submission status: Accepted

Solution code:
def main():
    import sys
    input = sys.stdin.readline

    INF = 10 ** 18

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

    G = [[] for _ in range(N + 1)]
    for _ in range(M):
        L, R, C = map(int, input().split())
        G[L].append([C, R])
        G[R].append([C, L])

    for i in range(1, N):
        G[i + 1].append([0, i])

    d = [INF] * (N + 1)

    def dijkstra(s):
        from heapq import heappop, heappush
        d[s] = 0
        pque = []
        heappush(pque, [0, s])
        
        while pque:
            p = heappop(pque)
            v = p[1]
            if d[v] < p[0]:
                continue
            for i in range(len(G[v])):
                e = G[v][i]
                if d[e[1]] > d[v] + e[0]:
                    d[e[1]] = d[v] + e[0]
                    heappush(pque, [d[e[1]], e[1]])

    dijkstra(1)

    print (-1 if d[-1] == INF else d[-1])

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
INF = 10 ** 18

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

G = [[] for _ in range(N + 1)]
for _ in range(M):
    L, R, C = map(int, input().split())
    G[L].append([C, R])
    G[R].append([C, L])

for i in range(1, N):
    G[i + 1].append([0, i])

d = [INF] * (N + 1)

def dijkstra(s):
    import heapq
    d[s] = 0
    pque = []
    heapq.heappush(pque, [0, s])
    
    while pque:
        p = heapq.heappop(pque)
        v = p[1]
        if d[v] < p[0]:
            continue
        for i in range(len(G[v])):
            e = G[v][i]
            if d[e[1]] > d[v] + e[0]:
                d[e[1]] = d[v] + e[0]
                heapq.heappush(pque, [d[e[1]], e[1]])

dijkstra(1)

print (-1 if d[-1] == INF else d[-1])

Submission status: Accepted

Solution code:
def main():
    import sys
    input = sys.stdin.readline
    sys.setrecursionlimit(10 ** 9)

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

    lst = [tuple(map(int, input().split())) for _ in range(M)]
    lst.sort(key = lambda x: x[1])
    lst.sort(key = lambda x: x[0])

    #セグメント木
    #次の2つの処理をO(log N)で実施することができる
    # s, tが与えられた時、区間[s, t)の最小値を求める
    # i, xが与えられた時、a_iの値をxに変更する

    INIT = 10 ** 18 #初期値 答えに関係ないもの
    MAX_N = 10 ** 6 #与えられる要素数の最大
    # INIT = 100
    data = [INIT] * (2 * MAX_N - 1) #MAX_Nで初期化

    #ここに機能をもたせる
    def func(vl, vr):
        return min(vl, vr)

    def init(n_):
        #簡単のため要素数を2のべき乗に
        n = 1
        while n < n_:
            n *= 2
        return n

    # N = int(input()) #配列の数
    n = init(N)

    def update(k, a): #k番目の値をaに変更 0-index
        # B[a] = k
        k += n - 1
        data[k] = a
        while k > 0: #登りながら更新
            k = (k - 1)//2
            data[k] = func(data[k * 2 + 1], data[k * 2 + 2])

    def query(a, b, k = 0, l = 0, r = n):
        if r <= a or b <= l:
            return INIT
        if a <= l and r <= b:
            return data[k]
        else:
            vl = query(a, b, k * 2 + 1, l, (l + r)//2)
            vr = query(a, b, k * 2 + 2, (l + r)//2, r)
            return func(vl, vr)

    def initialize(A): #リストAを与えて初期化する
        for i, a in enumerate(A):
            data[i + n - 1] = a
            # B[a] = i
        for i in range((2 * n - 3)//2, -1, -1):
            data[i] = func(data[i * 2 + 1], data[i * 2 + 2])

    # def index(a): #要素aがもとのどこに保存されているかを返す関数
    #     return B[a]

    def value(index): #indexが与えられた時、index番目の値を得る
        return data[index + n - 1]

    #初期値の入力
    D = [INIT] * N
    D[0] = 0
    # B = dict() #同じ要素がないのが前提 0-index管理
    initialize(D)

    #クエリの数
    # print (lst)
    # print (D)
    for a, b, c in lst:
        a -= 1
        b -= 1
        tmp = query(a, b)
        if D[b] > tmp + c:
            D[b] = tmp + c
            update(b, tmp + c)
        # print (D)

    # print (D)
    print (-1 if D[N - 1] == INIT else D[N - 1])

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 9)

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

lst = [tuple(map(int, input().split())) for _ in range(M)]
lst.sort(key = lambda x: x[1])
lst.sort(key = lambda x: x[0])

#セグメント木
#次の2つの処理をO(log N)で実施することができる
# s, tが与えられた時、区間[s, t)の最小値を求める
# i, xが与えられた時、a_iの値をxに変更する

INIT = 10 ** 18 #初期値 答えに関係ないもの
MAX_N = 10 ** 6 #与えられる要素数の最大
# INIT = 100
data = [INIT] * (2 * MAX_N - 1) #MAX_Nで初期化

#ここに機能をもたせる
def func(vl, vr):
    return min(vl, vr)

def init(n_):
    #簡単のため要素数を2のべき乗に
    n = 1
    while n < n_:
        n *= 2
    return n

# N = int(input()) #配列の数
n = init(N)

def update(k, a): #k番目の値をaに変更 0-index
    # B[a] = k
    k += n - 1
    data[k] = a
    while k > 0: #登りながら更新
        k = (k - 1)//2
        data[k] = func(data[k * 2 + 1], data[k * 2 + 2])

def query(a, b, k = 0, l = 0, r = n):
    if r <= a or b <= l:
        return INIT
    if a <= l and r <= b:
        return data[k]
    else:
        vl = query(a, b, k * 2 + 1, l, (l + r)//2)
        vr = query(a, b, k * 2 + 2, (l + r)//2, r)
        return func(vl, vr)

def initialize(A): #リストAを与えて初期化する
    for i, a in enumerate(A):
        data[i + n - 1] = a
        # B[a] = i
    for i in range((2 * n - 3)//2, -1, -1):
        data[i] = func(data[i * 2 + 1], data[i * 2 + 2])

# def index(a): #要素aがもとのどこに保存されているかを返す関数
#     return B[a]

def value(index): #indexが与えられた時、index番目の値を得る
    return data[index + n - 1]

#初期値の入力
D = [INIT] * N
D[0] = 0
# B = dict() #同じ要素がないのが前提 0-index管理
initialize(D)

#クエリの数
# print (lst)
# print (D)
for a, b, c in lst:
    a -= 1
    b -= 1
    tmp = query(a, b)
    if D[b] > tmp + c:
        D[b] = tmp + c
        update(b, tmp + c)
    # print (D)

# print (D)
print (-1 if D[N - 1] == INIT else D[N - 1])

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
import sys, math, itertools, collections, bisect
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
inf = float('inf') ;mod = 10**9+7
minans = inf ;ans = 0 ;count = 0 ;pro = 1

L,n=map(int,input().split())
lrc=[]
for i in range(n):
    l,r,c=map(int,input().split()); l-=1; r-=1
    lrc.append((l,r,c))
lrc.sort(key=lambda tup:tup[1])
class Segment_Tree:
    __slots__ = ['ide_ele', 'size', 'num', 'seg', 'segfunc']

    def __init__(self, size, func, element):
        #####単位元######
        self.ide_ele = element
        self.size = size

        #num:n以上の最小の2のべき乗
        self.num = 2 ** (self.size - 1).bit_length()
        self.seg = [self.ide_ele] * 2 * self.num

        #####segfunc######
        self.segfunc = func

    def apply(self, apply_seq):
        #set_val
        for i in range(self.size):
            self.seg[i + self.num - 1] = apply_seq[i]    
        #built
        for i in range(self.num - 2, -1, -1) :
            self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2]) 
        
    def update(self, k, x):
        k += self.num - 1
        self.seg[k] = x
        while k:
            k = (k-1) // 2
            self.seg[k] = self.segfunc(self.seg[k * 2 + 1],  self.seg[k * 2 + 2])
        
    def query(self, p, q):
        if q <= p:
            return self.ide_ele
        p += self.num - 1
        q += self.num - 2
        res = self.ide_ele
        while q - p > 1:
            if p & 1 == 0:
                res = self.segfunc(res, self.seg[p])
            if q & 1 == 1:
                res = self.segfunc(res, self.seg[q])
                q -= 1
            p = p // 2
            q = (q - 1) // 2 
        if p == q:
            res = self.segfunc(res, self.seg[p])
        else:
            res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
        return res


dp=[inf]*L; dp[0]=0
seg=Segment_Tree(L,min,inf)
seg.apply(dp)
for l,r,c in lrc:
    dp[r]=min(dp[r],seg.query(l,r)+c)
    seg.update(r,dp[r])
print(dp[L-1] if dp[L-1] != inf else -1)

Submission status: Accepted

Solution code:
import heapq


class Edge:
    def __init__(self, dst, weight):
        self.dst, self.weight = dst, weight

    def __lt__(self, e):
        return self.weight > e.weight


class Graph:
    def __init__(self, V):
        self.V = V
        self.E = [[] for _ in range(V)]

    def add_edge(self, src, dst, weight):
        self.E[src].append(Edge(dst, weight))


class ShortestPath:
    """Dijkstra's algorithm : find the shortest path from a vertex
       Complexity: O(E + log(V))
       used in GRL1A(AOJ)
    """

    def __init__(self, G, INF=10**9):
        """ V: the number of vertexes
            E: adjacency list (all edge in E must be 0 or positive)
            start: start vertex
            INF: Infinity distance
        """
        self.G, self.INF = G, INF

    class Node:
        def __init__(self, v, cost):
            self.v, self.cost = v, cost

        def __lt__(self, n):
            return self.cost < n.cost

    def dijkstra(self, start, goal=None):
        que = list()
        self.dist = [self.INF] * self.G.V  # distance from start
        self.prev = [-1] * self.G.V  # prev vertex of shortest path
        self.dist[start] = 0
        heapq.heappush(que, self.Node(start, 0))

        while len(que) > 0:
            n = heapq.heappop(que)
            if self.dist[n.v] < n.cost:
                continue
            if goal is not None and n.v == goal:
                return
            for e in self.G.E[n.v]:
                if self.dist[n.v] + e.weight < self.dist[e.dst]:
                    self.dist[e.dst] = self.dist[n.v] + e.weight
                    heapq.heappush(que, self.Node(e.dst, self.dist[e.dst]))
                    self.prev[e.dst] = n.v

    def getPath(self, end):
        path = [end]
        while self.prev[end] != -1:
            end = self.prev[end]
        return path[::-1]


N, M = map(int, input().split())
g = Graph(N)
for i in range(M):
    l, r, c = map(int, input().split())
    g.add_edge(l - 1, r - 1, c)

for i in range(N - 1):
    g.add_edge(i + 1, i, 0)
sp = ShortestPath(g, INF=10 ** 18)

sp.dijkstra(0)
if sp.dist[-1] == 10 ** 18:
    print(-1)
else:
    print(sp.dist[-1])

Submission status: Accepted

Solution code:
def main():
    from sys import stdin
    input = stdin.readline

    import numpy as np
    n, m = map(int, input().split())
    abc = [list(map(int, input().split())) for _ in [0]*m]
    g = [[] for _ in [0]*n]
    [g[u-1].append([v-1, c]) for u, v, c in abc]
    [g[i+1].append([i, 0]) for i in range(n-1)]

    import heapq

    yen = np.full(n, np.inf)
    h = [(0, 0)]
    heapq.heapify(h)
    while h:
        d, i = heapq.heappop(h)
        if yen[i] == np.inf:
            yen[i] = d
            for x, y in g[i]:
                heapq.heappush(h, (d+y, x))
    if yen[n-1] == np.inf:
        print(-1)
        return 0
    print(int(yen[n-1]))


main()

Submission status: Accepted

Solution code:
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce


sys.setrecursionlimit(2147483647)
INF = 1 << 100
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007


n, m = LI()
G = [[] for _ in range(n)]
for _ in range(m):
    l, r, c = LI()
    G[l - 1] += [(r - 1, c)]


for i in range(n - 1):
    G[i + 1] += [(i, 0)]


def dijkstra(G, s=0):
    hq = [(0, s)]
    dist = [INF] * n
    dist[s] = 0
    checked = [0] * n
    while hq:
        min_dist, u = heappop(hq)
        if checked[u]:
            continue
        checked[u] = 1
        for v, c in G[u]:
            if checked[v]:
                continue
            elif dist[u] + c < dist[v]:
                dist[v] = dist[u] + c
                heappush(hq, (dist[u] + c, v))
    return dist


ans = dijkstra(G)[-1]
if ans == INF:
    print(-1)
else:
    print(ans)