結果
| 問題 |
No.2436 Min Diff Distance
|
| コンテスト | |
| ユーザー |
👑 SPD_9X2
|
| 提出日時 | 2023-08-19 05:17:45 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,929 ms / 2,000 ms |
| コード長 | 3,596 bytes |
| コンパイル時間 | 166 ms |
| コンパイル使用メモリ | 82,220 KB |
| 実行使用メモリ | 144,528 KB |
| 最終ジャッジ日時 | 2024-11-28 18:59:27 |
| 合計ジャッジ時間 | 26,874 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
ソースコード
"""
殴るのが正解…?
チェビシェフ距離に置き換えられる
典型っぽいからちゃんと解いておこう
各点について、最遠点と最近点を求められれば終わり
最大は、X+Y,X-Y の最大・最小だけ考えればいいんだった
"""
import sys
from sys import stdin
#0-indexed , 半開区間[a,b)
#calc変更で演算変更
class SegTreeMin:
def __init__(self,N,first):
self.NO = 2**(N-1).bit_length()
self.First = first
self.data = [first] * (2*self.NO)
def calc(self,l,r):
return min(l,r)
def update(self,ind,x):
ind += self.NO - 1
self.data[ind] = x
while ind >= 0:
ind = (ind - 1)//2
self.data[ind] = self.calc(self.data[2*ind+1],self.data[2*ind+2])
def query(self,l,r):
L = l + self.NO
R = r + self.NO
s = self.First
while L < R:
if R & 1:
R -= 1
s = self.calc(s , self.data[R-1])
if L & 1:
s = self.calc(s , self.data[L-1])
L += 1
L >>= 1
R >>= 1
return s
def get(self , ind):
ind += self.NO - 1
return self.data[ind]
#0-indexed , 半開区間[a,b)
#calc変更で演算変更
class SegTreeMax:
def __init__(self,N,first):
self.NO = 2**(N-1).bit_length()
self.First = first
self.data = [first] * (2*self.NO)
def calc(self,l,r):
return max(l,r)
def update(self,ind,x):
ind += self.NO - 1
self.data[ind] = x
while ind >= 0:
ind = (ind - 1)//2
self.data[ind] = self.calc(self.data[2*ind+1],self.data[2*ind+2])
def query(self,l,r):
L = l + self.NO
R = r + self.NO
s = self.First
while L < R:
if R & 1:
R -= 1
s = self.calc(s , self.data[R-1])
if L & 1:
s = self.calc(s , self.data[L-1])
L += 1
L >>= 1
R >>= 1
return s
def get(self , ind):
ind += self.NO - 1
return self.data[ind]
inf = float("inf")
N = int(stdin.readline())
XY = []
for i in range(N):
X,Y = map(int,stdin.readline().split())
XY.append( (X,Y) )
XY.sort()
# 各頂点について、最遠点を求める
# まず、X+Y,X-Y の最大・最小を集める
a,b,A,B = inf,inf,-inf,-inf
for X,Y in XY:
p = X+Y
m = X-Y
a = min(a,p)
A = max(A,p)
b = min(b,m)
B = max(B,m)
# 後は4通り試す
XD = [0] * N
for i,(X,Y) in enumerate(XY):
p = X+Y
m = X-Y
XD[i] = max( abs(a-p) , abs(A-p) , abs(b-m) , abs(B-m) )
#print (XD)
# 最近点を考える
SSS = 500000
foot = SSS//2
ND = [inf] * N
segAX = SegTreeMax(SSS,float("-inf"))
segBX = SegTreeMax(SSS,float("-inf"))
for i,(X,Y) in enumerate(XY):
a = X+Y
b = X-Y
ND[i] = min(ND[i] , a - segAX.query(0,foot+Y) , b - segBX.query(foot+Y,SSS))
if segAX.get(foot+Y) < a:
segAX.update(foot+Y,a)
if segBX.get(foot+Y) < b:
segBX.update(foot+Y,b)
segAN = SegTreeMin(SSS,inf)
segBN = SegTreeMin(SSS,inf)
for i,(X,Y) in enumerate(reversed(XY)):
i = N-1-i
a = X+Y
b = X-Y
ND[i] = min(ND[i] , segBN.query(0,foot+Y) - b , segAN.query(foot+Y,SSS) - a)
if segAN.get(foot+Y) > a:
segAN.update( foot+Y , a )
if segBN.get(foot+Y) > b:
segBN.update( foot+Y , b )
#print (ND)
ans = inf
for x,n in zip(XD,ND):
ans = min(ans , x-n)
print (ans)
SPD_9X2