結果
問題 | No.1920 Territory |
ユーザー | とりゐ |
提出日時 | 2022-03-25 10:30:29 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 3,148 ms / 5,000 ms |
コード長 | 4,307 bytes |
コンパイル時間 | 257 ms |
コンパイル使用メモリ | 82,688 KB |
実行使用メモリ | 169,332 KB |
最終ジャッジ日時 | 2024-06-28 15:53:04 |
合計ジャッジ時間 | 55,064 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 127 ms
120,320 KB |
testcase_01 | AC | 140 ms
116,048 KB |
testcase_02 | AC | 126 ms
120,064 KB |
testcase_03 | AC | 393 ms
122,712 KB |
testcase_04 | AC | 415 ms
124,260 KB |
testcase_05 | AC | 394 ms
123,088 KB |
testcase_06 | AC | 397 ms
122,592 KB |
testcase_07 | AC | 391 ms
120,540 KB |
testcase_08 | AC | 370 ms
120,536 KB |
testcase_09 | AC | 400 ms
122,964 KB |
testcase_10 | AC | 416 ms
123,116 KB |
testcase_11 | AC | 396 ms
121,556 KB |
testcase_12 | AC | 439 ms
117,532 KB |
testcase_13 | AC | 2,830 ms
161,892 KB |
testcase_14 | AC | 3,029 ms
161,760 KB |
testcase_15 | AC | 3,096 ms
161,632 KB |
testcase_16 | AC | 3,148 ms
163,168 KB |
testcase_17 | AC | 2,798 ms
161,376 KB |
testcase_18 | AC | 2,764 ms
160,580 KB |
testcase_19 | AC | 2,894 ms
164,552 KB |
testcase_20 | AC | 2,651 ms
163,788 KB |
testcase_21 | AC | 2,962 ms
163,656 KB |
testcase_22 | AC | 2,688 ms
162,120 KB |
testcase_23 | AC | 1,232 ms
152,944 KB |
testcase_24 | AC | 1,155 ms
169,332 KB |
testcase_25 | AC | 1,198 ms
162,364 KB |
testcase_26 | AC | 1,174 ms
162,740 KB |
testcase_27 | AC | 1,272 ms
160,040 KB |
testcase_28 | AC | 1,278 ms
160,284 KB |
testcase_29 | AC | 1,480 ms
168,056 KB |
testcase_30 | AC | 1,421 ms
168,952 KB |
testcase_31 | AC | 2,469 ms
165,196 KB |
testcase_32 | AC | 2,562 ms
164,164 KB |
testcase_33 | AC | 1,946 ms
165,100 KB |
testcase_34 | AC | 1,904 ms
165,340 KB |
ソースコード
from sys import stdin input=lambda :stdin.readline()[:-1] class UnionFind(): def __init__(self, n): self.n = n self.parents = [-1] * n def find(self, x): if self.parents[x] < 0: return x else: self.parents[x] = self.find(self.parents[x]) return self.parents[x] def union(self, x, y): x = self.find(x) y = self.find(y) if x == y: return if self.parents[x] > self.parents[y]: x, y = y, x self.parents[x] += self.parents[y] self.parents[y] = x def same(self, x, y): return self.find(x) == self.find(y) def roots(self): return [i for i, x in enumerate(self.parents) if x < 0] class SegTree: def __init__(self, init_val, segfunc, ide_ele): n = len(init_val) self.segfunc = segfunc self.ide_ele = ide_ele self.num = 1 << (n - 1).bit_length() self.tree = [ide_ele] * 2 * self.num for i in range(n): self.tree[self.num + i] = init_val[i] for i in range(self.num - 1, 0, -1): self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1]) def update(self, k, x): k += self.num self.tree[k] = x while k > 1: self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1]) k >>= 1 def query(self, l, r): res = self.ide_ele l += self.num r += self.num while l < r: if l & 1: res = self.segfunc(res, self.tree[l]) l += 1 if r & 1: res = self.segfunc(res, self.tree[r - 1]) l >>= 1 r >>= 1 return res class ordered_set: def __init__(self,size): self.inf=10**9 self.size=size def segfunc(x,y):return max(x,y) self.seg_max=SegTree([-self.inf]*size,segfunc,-self.inf) def segfunc(x,y):return min(x,y) self.seg_min=SegTree([self.inf]*size,segfunc,self.inf) def add(self,x): self.seg_max.update(x,x) self.seg_min.update(x,x) def remove(self,x): self.seg_max.update(x,-self.inf) self.seg_min.update(x,self.inf) def get_max(self,x): # x より小さい最大元 return self.seg_max.query(0,x) def get_min(self,x): # x より大きい最小元 return self.seg_min.query(x+1,self.size) n,m=map(int,input().split()) query=[] for i in range(n): y,x1,x2=map(int,input().split()) query.append((3*x1-1,3,y,0)) query.append((3*x2+1,2,y,0)) for i in range(m): x,y1,y2=map(int,input().split()) query.append((3*x,1,y1,y2)) query.sort(key=lambda x:x[0]) k=2*10**5+10 inf=10**9 uf=UnionFind(k) set1=ordered_set(k) # y 座標の集合を管理 set2=ordered_set(k) # 区間の左端の集合を管理 ans=-n-m use=[0]*(k) itv_right=[-1]*k # 区間の右端を記録 for x,t,y1,y2 in query: if t==1: # y 軸に平行な線分の処理 if set1.get_max(y2+1)<y1: ans+=1 continue L=set2.get_max(y1+1) if L!=-inf and itv_right[L]>=y1: pass else: L=set2.get_min(y1-1) if L>y2: ans+=1 continue R=itv_right[L] while R<=y2: l=set2.get_min(R) if l>y2: break R=itv_right[l] itv_right[l]=-1 set2.remove(l) uf.union(L,l) itv_right[L]=R if t==2: # x 軸に平行な線分の削除 set1.remove(y1) L=set2.get_max(y1+1) R=itv_right[L] itv_right[L]=-1 r=set1.get_max(y1) l=set1.get_min(y1) if L!=y1: itv_right[L]=r else: set2.remove(y1) if R!=y1: itv_right[l]=R set2.add(l) if t==3: # x 軸に平行な線分の追加 use[y1]=1 L=set2.get_max(y1) if L!=-inf: R=itv_right[L] if y1<=R: r=set1.get_max(y1) l=set1.get_min(y1) itv_right[L]=r set2.add(l) itv_right[l]=R itv_right[y1]=y1 set1.add(y1) set2.add(y1) for i in uf.roots(): if use[i]==1: ans+=1 def segfunc(x,y): return x+y seg=SegTree([0]*k,segfunc,0) for x,t,y1,y2 in query: if t==1: ans+=seg.query(y1,y2+1) if t==2: seg.update(y1,0) if t==3: seg.update(y1,1) print(ans)