結果
| 問題 |
No.614 壊れたキャンパス
|
| コンテスト | |
| ユーザー |
tktk_snsn
|
| 提出日時 | 2021-05-30 12:13:12 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,685 bytes |
| コンパイル時間 | 274 ms |
| コンパイル使用メモリ | 82,304 KB |
| 実行使用メモリ | 137,072 KB |
| 最終ジャッジ日時 | 2024-11-08 20:43:40 |
| 合計ジャッジ時間 | 11,050 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 15 WA * 5 |
ソースコード
import sys
import bisect
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)
class SegTree(object):
def __init__(self, N, op_data, u_data):
self._n = N
self.log = (N-1).bit_length()
self.size = 1 << self.log
self.op = op_data
self.e = u_data
self.data = [u_data] * (2 * self.size)
# self.len = [1] * (2 * self.size)
def _update(self, i):
self.data[i] = self.op(self.data[i << 1], self.data[i << 1 | 1])
def initialize(self, arr=None):
""" segtreeをarrで初期化する。len(arr) == Nにすること """
if arr:
for i, a in enumerate(arr, self.size):
self.data[i] = a
for i in reversed(range(1, self.size)):
self._update(i)
# self.len[i] = self.len[i << 1] + self.len[i << 1 | 1]
def update(self, p, x):
""" data[p] = x とする (0-indexed)"""
p += self.size
self.data[p] = x
for i in range(1, self.log + 1):
self._update(p >> i)
def get(self, p):
""" data[p]を返す """
return self.data[p + self.size]
def prod(self, l, r):
"""
op_data(data[l], data[l+1], ..., data[r-1])を返す (0-indexed)
"""
sml = self.e
smr = self.e
l += self.size
r += self.size
while l < r:
if l & 1:
sml = self.op(sml, self.data[l])
l += 1
if r & 1:
r -= 1
smr = self.op(self.data[r], smr)
l >>= 1
r >>= 1
return self.op(sml, smr)
def all_prod(self):
""" op(data[0], data[1], ... data[N-1])を返す """
return self.data[1]
def max_right(self, l, func):
"""
func(l, l+1, ..., r-1) = True,
func(l, l+1, ..., r-1, r) = Falseとなる r を返す
"""
if l == self._n:
return self._n
l += self.size
sm = self.e
while True:
while l % 2 == 0:
l >>= 1
if not func(self.op(sm, self.data[l])):
while l < self.size:
l <<= 1
if func(self.op(sm, self.data[l])):
sm = self.op(sm, self.data[l])
l += 1
return l - self.size
sm = self.op(sm, self.data[l])
l += 1
if (l & -l) == l:
break
return self._n
def min_left(self, r, func):
"""
func( l, l+1, ..., r-1) = True,
func(l-1, l, l+1, ..., r-1) = Falseとなる l を返す
"""
if r == 0:
return 0
r += self.size
sm = self.e
while True:
r -= 1
while r > 1 and r & 1:
r >>= 1
if not func(self.op(self.data[r], sm)):
while r < self.size:
r = r << 1 | 1
if func(self.op(self.data[r], sm)):
sm = self.op(self.data[r], sm)
r -= 1
return r + 1 - self.size
sm = self.op(self.data[r], sm)
if (r & -r) == r:
break
return 0
def op_right(L, R):
if R[1] == -1:
return L
if L[1] == -1:
return R
if sum(L) < sum(R):
return L
return R
def op_left(L, R):
if R[1] == -1:
return L
if L[1] == -1:
return R
if L[0] - L[1] < R[0] - R[1]:
return L
return R
inf = 10 ** 9
u_data = (inf, -1) # cost, pos
N, M, K, S, T = map(int, input().split())
stair = [[] for _ in range(N)]
for _ in range(M):
a, b, c = map(int, input().split())
a -= 1
stair[a].append((c, b))
for i in range(N):
stair[i].sort()
if not stair[0]:
print(-1)
exit()
pos = []
cost = []
for c, b in stair[0]:
pos.append(c)
cost.append(abs(b - S))
for i in range(1, N-1):
if not stair[i]:
print(-1)
exit()
memo = []
for c, b in stair[i]:
m = bisect.bisect_right(pos, b)
memo.append(m + 1)
pc = [u_data] + [(c, p) for p, c in zip(pos, cost)] + [u_data]
size = len(pc)
segL = SegTree(size, op_left, u_data)
segL.initialize(pc)
segR = SegTree(size, op_right, u_data)
segR.initialize(pc)
pos = []
cost = []
for (c, b), m in zip(stair[i], memo):
Lc, Lp = segL.prod(0, m)
Rc, Rp = segR.prod(m, size)
pos.append(c)
cost.append(min(Lc + b - Lp, Rc + Rp - b))
ans = inf
for p, c in zip(pos, cost):
ans = min(ans, c + abs(p - T))
print(ans)
tktk_snsn