結果
問題 | No.674 n連勤 |
ユーザー |
![]() |
提出日時 | 2021-02-14 20:05:53 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,047 ms / 2,000 ms |
コード長 | 6,620 bytes |
コンパイル時間 | 210 ms |
コンパイル使用メモリ | 82,048 KB |
実行使用メモリ | 99,044 KB |
最終ジャッジ日時 | 2024-07-22 06:46:29 |
合計ジャッジ時間 | 4,600 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 17 |
ソースコード
import sysinput = sys.stdin.buffer.readlinefrom bisect import bisect_left, bisect_right, insortclass BTreeNode:def __init__(self, B_SIZE):self.B_SIZE = B_SIZEself.keys = []self.children = []def split(self):if len(self.keys) != self.B_SIZE * 2:return Noneptr = BTreeNode(self.B_SIZE)ptr.keys, self.keys = self.keys[:self.B_SIZE], self.keys[self.B_SIZE:]ptr.children, self.children = self.children[:self.B_SIZE], self.children[self.B_SIZE:]return ptrdef shift_lr(self, idx):ptrl, ptrr = self.children[idx], self.children[idx + 1]ptrr.keys.insert(0, ptrl.keys[-1])del ptrl.keys[-1]if ptrl.children:ptrr.children.insert(0, ptrl.children[-1])del ptrl.children[-1]self.keys[idx], ptrr.keys[0] = ptrr.keys[0], self.keys[idx]def shift_rl(self, idx):ptrl, ptrr = self.children[idx], self.children[idx + 1]ptrl.keys.append(ptrr.keys[0])del ptrr.keys[0]if ptrr.children:ptrl.children.append(ptrr.children[0])del ptrr.children[0]self.keys[idx], ptrl.keys[-1] = ptrl.keys[-1], self.keys[idx]def merge(self, idx):self.children[idx].keys += [self.keys[idx]] + self.children[idx + 1].keysself.children[idx].children += self.children[idx + 1].childrendel self.keys[idx], self.children[idx + 1]assert(len(self.keys) + 1 == len(self.children))class SortedSetBTree:def __init__(self, B_SIZE=512):self.B_SIZE = B_SIZEself.root = BTreeNode(self.B_SIZE)self.size = 0def __contains__(self, key):return self._search(key)def __len__(self):return self.sizedef __iter__(self):return self._generate_rec(self.root)def _search(self, key):ptr = self.rootwhile True:idx = bisect_left(ptr.keys, key)if idx != len(ptr.keys) and ptr.keys[idx] == key:return Trueif not ptr.children:return Falseptr = ptr.children[idx]def _generate_rec(self, ptr):for idx, chi in enumerate(ptr.children):yield from self._generate_rec(chi)if idx < len(ptr.keys):yield ptr.keys[idx]if not ptr.children:for key in ptr.keys:yield keydef _generate_rec_kl(self, ptr, kl, f):idxl = 0 if f else bisect_left(ptr.keys, kl)for idx, chi in enumerate(ptr.children[idxl:], idxl):if idx == idxl:yield from self._generate_rec_kl(chi, kl, f | False)else:yield from self._generate_rec_kl(chi, kl, True)if idx < len(ptr.keys):yield ptr.keys[idx]if not ptr.children:for key in ptr.keys[idxl:]:yield keydef _add_rec(self, ptr, key):if not ptr.children:insort(ptr.keys, key)else:i = bisect_right(ptr.keys, key)p = self._add_rec(ptr.children[i], key)if p is not None:ptr.keys.insert(i, p.keys.pop())ptr.children.insert(i, p)return ptr.split()def _remove_rec(self, ptr, key):idx = bisect_left(ptr.keys, key)if idx != len(ptr.keys) and ptr.keys[idx] == key:if not ptr.children:del ptr.keys[idx]else:ptr.keys[idx] = self._remove_smallest(ptr.children[idx + 1])self._check_underflow(ptr, idx + 1)return Trueelif ptr.children and self._remove_rec(ptr.children[idx], key):self._check_underflow(ptr, idx)return Truereturn Falsedef _remove_smallest(self, ptr):if not ptr.children:res = ptr.keys[0]del ptr.keys[0]return resres = self._remove_smallest(ptr.children[0])self._check_underflow(ptr, 0)return resdef _check_underflow(self, ptr, idx):if len(ptr.children[idx].keys) >= self.B_SIZE - 1:returnelif idx == 0:if len(ptr.children[idx + 1].keys) > self.B_SIZE: ptr.shift_rl(idx)else: ptr.merge(idx)else:if len(ptr.children[idx - 1].keys) > self.B_SIZE: ptr.shift_lr(idx - 1)else: ptr.merge(idx - 1)def add(self, key):if key in self:return Trueptr = self.rootp = self._add_rec(ptr, key)if p is not None:root = BTreeNode(self.B_SIZE)root.keys = [p.keys.pop()]root.children = [p, self.root]self.root = rootself.size += 1return Truedef remove(self, key):flag = self._remove_rec(self.root, key)if len(self.root.children) == 1:self.root = self.root.children[0]if flag: self.size -= 1return flagdef iterate(self, kl):return self._generate_rec_kl(self.root, kl, False)def prev_key(self, key):ptr = self.rootres = Nonewhile True:idx = bisect_left(ptr.keys, key)if idx - 1 >= 0:res = ptr.keys[idx - 1]if not ptr.children:breakptr = ptr.children[idx]return resclass SortedInterval:def __init__(self):self.sset = SortedSetBTree()self.rs = {}self.length = 0def add(self, l, r):prev_l = self.sset.prev_key(l)if prev_l is not None and l <= self.rs[prev_l]:l = prev_lr = max(r, self.rs[prev_l])del self.rs[prev_l]self.sset.remove(prev_l)removed = []for next_l in self.sset.iterate(l):if next_l > r:breakremoved.append(next_l)for next_l in removed:r = max(r, self.rs[next_l])del self.rs[next_l]self.sset.remove(next_l)self.sset.add(l)self.rs[l] = r# 新しく生成された区間の大きさを返すreturn r - ldef __iter__(self):for l in self.sset:yield l, self.rs[l]n, q = map(int, input().split())intervals = [list(map(int, input().split())) for i in range(q)]si = SortedInterval()ans = 0res = []for l, r in intervals:ans = max(si.add(l, r + 1), ans)res.append(ans)print("\n".join(map(str, res)))