結果
問題 | No.1920 Territory |
ユーザー | とりゐ |
提出日時 | 2022-03-25 10:18:57 |
言語 | PyPy3 (7.3.15) |
結果 |
RE
|
実行時間 | - |
コード長 | 4,305 bytes |
コンパイル時間 | 522 ms |
コンパイル使用メモリ | 82,048 KB |
実行使用メモリ | 148,460 KB |
最終ジャッジ日時 | 2024-06-28 15:50:55 |
合計ジャッジ時間 | 34,970 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 92 ms
92,416 KB |
testcase_01 | AC | 98 ms
94,208 KB |
testcase_02 | AC | 94 ms
92,928 KB |
testcase_03 | RE | - |
testcase_04 | RE | - |
testcase_05 | RE | - |
testcase_06 | RE | - |
testcase_07 | RE | - |
testcase_08 | AC | 365 ms
102,616 KB |
testcase_09 | AC | 377 ms
101,592 KB |
testcase_10 | AC | 377 ms
102,748 KB |
testcase_11 | AC | 350 ms
96,976 KB |
testcase_12 | AC | 397 ms
101,460 KB |
testcase_13 | RE | - |
testcase_14 | RE | - |
testcase_15 | RE | - |
testcase_16 | RE | - |
testcase_17 | RE | - |
testcase_18 | AC | 2,759 ms
144,456 KB |
testcase_19 | AC | 2,801 ms
143,948 KB |
testcase_20 | AC | 2,768 ms
144,320 KB |
testcase_21 | AC | 2,646 ms
144,072 KB |
testcase_22 | AC | 2,700 ms
144,080 KB |
testcase_23 | AC | 1,228 ms
133,356 KB |
testcase_24 | AC | 1,189 ms
148,460 KB |
testcase_25 | RE | - |
testcase_26 | RE | - |
testcase_27 | AC | 1,208 ms
143,012 KB |
testcase_28 | AC | 1,207 ms
142,760 KB |
testcase_29 | RE | - |
testcase_30 | RE | - |
testcase_31 | AC | 2,654 ms
145,352 KB |
testcase_32 | AC | 2,478 ms
145,360 KB |
testcase_33 | RE | - |
testcase_34 | RE | - |
ソースコード
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=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)