結果
問題 | No.2436 Min Diff Distance |
ユーザー | 👑 SPD_9X2 |
提出日時 | 2023-08-19 05:17:45 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 3,596 bytes |
コンパイル時間 | 170 ms |
コンパイル使用メモリ | 82,304 KB |
実行使用メモリ | 143,836 KB |
最終ジャッジ日時 | 2024-05-06 12:30:46 |
合計ジャッジ時間 | 32,649 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 103 ms
118,272 KB |
testcase_01 | AC | 102 ms
118,528 KB |
testcase_02 | AC | 103 ms
118,912 KB |
testcase_03 | TLE | - |
testcase_04 | TLE | - |
testcase_05 | TLE | - |
testcase_06 | TLE | - |
testcase_07 | TLE | - |
testcase_08 | TLE | - |
testcase_09 | AC | 103 ms
118,144 KB |
testcase_10 | AC | 103 ms
118,272 KB |
testcase_11 | AC | 990 ms
139,456 KB |
testcase_12 | AC | 737 ms
139,224 KB |
testcase_13 | AC | 1,640 ms
138,240 KB |
testcase_14 | AC | 748 ms
130,004 KB |
testcase_15 | TLE | - |
testcase_16 | AC | 1,274 ms
135,480 KB |
testcase_17 | AC | 1,948 ms
140,352 KB |
testcase_18 | AC | 1,844 ms
139,568 KB |
testcase_19 | AC | 1,974 ms
142,240 KB |
testcase_20 | AC | 1,538 ms
137,012 KB |
testcase_21 | AC | 1,011 ms
131,536 KB |
testcase_22 | AC | 738 ms
129,988 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)