結果
問題 | 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 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 71 ms
118,400 KB |
testcase_01 | AC | 77 ms
118,144 KB |
testcase_02 | AC | 71 ms
118,912 KB |
testcase_03 | AC | 1,827 ms
144,528 KB |
testcase_04 | AC | 1,854 ms
143,788 KB |
testcase_05 | AC | 1,929 ms
143,888 KB |
testcase_06 | AC | 1,874 ms
142,988 KB |
testcase_07 | AC | 1,785 ms
142,940 KB |
testcase_08 | AC | 1,834 ms
143,160 KB |
testcase_09 | AC | 72 ms
118,528 KB |
testcase_10 | AC | 69 ms
118,272 KB |
testcase_11 | AC | 845 ms
139,460 KB |
testcase_12 | AC | 627 ms
139,908 KB |
testcase_13 | AC | 1,368 ms
137,880 KB |
testcase_14 | AC | 613 ms
130,060 KB |
testcase_15 | AC | 1,879 ms
143,452 KB |
testcase_16 | AC | 1,091 ms
135,608 KB |
testcase_17 | AC | 1,647 ms
140,348 KB |
testcase_18 | AC | 1,557 ms
139,588 KB |
testcase_19 | AC | 1,621 ms
141,708 KB |
testcase_20 | AC | 1,270 ms
136,632 KB |
testcase_21 | AC | 829 ms
132,008 KB |
testcase_22 | AC | 602 ms
130,108 KB |
ソースコード
""" 殴るのが正解…? チェビシェフ距離に置き換えられる 典型っぽいからちゃんと解いておこう 各点について、最遠点と最近点を求められれば終わり 最大は、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)