結果
問題 | No.2796 Small Matryoshka |
ユーザー | 👑 seekworser |
提出日時 | 2024-06-28 22:02:23 |
言語 | Nim (2.0.2) |
結果 |
TLE
|
実行時間 | - |
コード長 | 18,700 bytes |
コンパイル時間 | 6,093 ms |
コンパイル使用メモリ | 92,160 KB |
実行使用メモリ | 13,568 KB |
最終ジャッジ日時 | 2024-06-28 22:02:36 |
合計ジャッジ時間 | 11,845 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | TLE | - |
testcase_01 | -- | - |
testcase_02 | -- | - |
testcase_03 | -- | - |
testcase_04 | -- | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
ソースコード
import macros;macro ImportExpand(s:untyped):untyped = parseStmt($s[2]) # source: https://github.com/kemuniku/cplib/tree/main/src/cplib/tmpl/citrus.nim ImportExpand "cplib/tmpl/citrus" <=== "when not declared CPLIB_TMPL_CITRUS:\n const CPLIB_TMPL_CITRUS* = 1\n {.warning[UnusedImport]: off.}\n {.hint[XDeclaredButNotUsed]: off.}\n import os\n import algorithm\n import sequtils\n import tables\n import macros\n import std/math\n import sets\n import strutils\n import strformat\n import sugar\n import streams\n import deques\n import bitops\n import heapqueue\n import options\n import hashes\n const MODINT998244353* = 998244353\n const MODINT1000000007* = 1000000007\n when not declared CPLIB_UTILS_CONSTANTS:\n const CPLIB_UTILS_CONSTANTS* = 1\n const INF32*: int32 = 100100111.int32\n const INF64*: int = int(3300300300300300491)\n \n const INFL = INF64\n type double* = float64\n let readNext = iterator(getsChar: bool = false): string {.closure.} =\n while true:\n var si: string\n try: si = stdin.readLine\n except EOFError: yield \"\"\n for s in si.split:\n if getsChar:\n for i in 0..<s.len():\n yield s[i..i]\n else:\n if s.isEmptyOrWhitespace: continue\n yield s\n proc input*(t: typedesc[string]): string = readNext()\n proc input*(t: typedesc[char]): char = readNext(true)[0]\n proc input*(t: typedesc[int]): int = readNext().parseInt\n proc input*(t: typedesc[float]): float = readNext().parseFloat\n macro input*(t: typedesc, n: varargs[int]): untyped =\n var repStr = \"\"\n for arg in n:\n repStr &= &\"({arg.repr}).newSeqWith \"\n parseExpr(&\"{repStr}input({t})\")\n macro input*(ts: varargs[auto]): untyped =\n var tupStr = \"\"\n for t in ts:\n tupStr &= &\"input({t.repr}),\"\n parseExpr(&\"({tupStr})\")\n macro input*(n: int, ts: varargs[auto]): untyped =\n for typ in ts:\n if typ.typeKind != ntyAnything:\n error(\"Expected typedesc, got \" & typ.repr, typ)\n parseExpr(&\"({n.repr}).newSeqWith input({ts.repr})\")\n proc `fmtprint`*(x: int or string or char or bool): string = return $x\n proc `fmtprint`*(x: float or float32 or float64): string = return &\"{x:.16f}\"\n proc `fmtprint`*[T](x: seq[T] or Deque[T] or HashSet[T] or set[T]): string = return x.toSeq.join(\" \")\n proc `fmtprint`*[T, N](x: array[T, N]): string = return x.toSeq.join(\" \")\n proc `fmtprint`*[T](x: HeapQueue[T]): string =\n var q = x\n while q.len != 0:\n result &= &\"{q.pop()}\"\n if q.len != 0: result &= \" \"\n proc `fmtprint`*[T](x: CountTable[T]): string =\n result = x.pairs.toSeq.mapIt(&\"{it[0]}: {it[1]}\").join(\" \")\n proc `fmtprint`*[K, V](x: Table[K, V]): string =\n result = x.pairs.toSeq.mapIt(&\"{it[0]}: {it[1]}\").join(\" \")\n proc print*(prop: tuple[f: File, sepc: string, endc: string, flush: bool], args: varargs[string, `fmtprint`]) =\n for i in 0..<len(args):\n prop.f.write(&\"{args[i]}\")\n if i != len(args) - 1: prop.f.write(prop.sepc) else: prop.f.write(prop.endc)\n if prop.flush: prop.f.flushFile()\n proc print*(args: varargs[string, `fmtprint`]) = print((f: stdout, sepc: \" \", endc: \"\\n\", flush: false), args)\n const LOCAL_DEBUG{.booldefine.} = false\n macro getSymbolName(x: typed): string = x.toStrLit\n macro debug*(args: varargs[untyped]): untyped =\n when LOCAL_DEBUG:\n result = newNimNode(nnkStmtList, args)\n template prop(e: string = \"\"): untyped = (f: stderr, sepc: \"\", endc: e, flush: true)\n for i, arg in args:\n if arg.kind == nnkStrLit:\n result.add(quote do: print(prop(), \"\\\"\", `arg`, \"\\\"\"))\n else:\n result.add(quote do: print(prop(\": \"), getSymbolName(`arg`)))\n result.add(quote do: print(prop(), `arg`))\n if i != args.len - 1: result.add(quote do: print(prop(), \", \"))\n else: result.add(quote do: print(prop(), \"\\n\"))\n else:\n return (quote do: discard)\n proc `%`*(x: SomeInteger, y: SomeInteger): int =\n result = x mod y\n if y > 0 and result < 0: result += y\n if y < 0 and result > 0: result += y\n proc `//`*(x: SomeInteger, y: SomeInteger): int =\n result = x div y\n if y > 0 and result * y > x: result -= 1\n if y < 0 and result * y < x: result -= 1\n proc `^`*(x: SomeInteger, y: SomeInteger): int = x xor y\n proc `&`*(x: SomeInteger, y: SomeInteger): int = x and y\n proc `|`*(x: SomeInteger, y: SomeInteger): int = x or y\n proc `>>`*(x: SomeInteger, y: SomeInteger): int = x shr y\n proc `<<`*(x: SomeInteger, y: SomeInteger): int = x shl y\n proc `%=`*(x: var SomeInteger, y: SomeInteger): void = x = x % y\n proc `//=`*(x: var SomeInteger, y: SomeInteger): void = x = x // y\n proc `^=`*(x: var SomeInteger, y: SomeInteger): void = x = x ^ y\n proc `&=`*(x: var SomeInteger, y: SomeInteger): void = x = x & y\n proc `|=`*(x: var SomeInteger, y: SomeInteger): void = x = x | y\n proc `>>=`*(x: var SomeInteger, y: SomeInteger): void = x = x >> y\n proc `<<=`*(x: var SomeInteger, y: SomeInteger): void = x = x << y\n proc `[]`*(x, n: int): bool = (x and (1 shl n)) != 0\n proc `[]=`*(x: var int, n: int, i: bool) =\n if i: x = x or (1 << n)\n else: (if x[n]: x = x xor (1 << n))\n proc pow*(a, n: int, m = INF64): int =\n var\n rev = 1\n a = a\n n = n\n while n > 0:\n if n % 2 != 0: rev = (rev * a) mod m\n if n > 1: a = (a * a) mod m\n n >>= 1\n return rev\n when not declared CPLIB_MATH_ISQRT:\n const CPLIB_MATH_ISQRT* = 1\n proc isqrt*(n: int): int =\n var x = n\n var y = (x + 1) shr 1\n while y < x:\n x = y\n y = (x + n div x) shr 1\n return x\n \n proc chmax*[T](x: var T, y: T): bool {.discardable.} = (if x < y: (x = y; return true; ) return false)\n proc chmin*[T](x: var T, y: T): bool {.discardable.} = (if x > y: (x = y; return true; ) return false)\n proc `max=`*[T](x: var T, y: T) = x = max(x, y)\n proc `min=`*[T](x: var T, y: T) = x = min(x, y)\n proc at*(x: char, a = '0'): int = int(x) - int(a)\n proc Yes*(b: bool = true): void = print(if b: \"Yes\" else: \"No\")\n proc No*(b: bool = true): void = Yes(not b)\n proc YES_upper*(b: bool = true): void = print(if b: \"YES\" else: \"NO\")\n proc NO_upper*(b: bool = true): void = Yes_upper(not b)\n const DXY* = [(0, -1), (0, 1), (-1, 0), (1, 0)]\n const DDXY* = [(1, -1), (1, 0), (1, 1), (0, -1), (0, 1), (-1, -1), (-1, 0), (-1, 1)]\n macro exit*(statement: untyped): untyped = (quote do: (`statement`; quit()))\n proc initHashSet[T](): Hashset[T] = initHashSet[T](0)\n" # source: https://github.com/kemuniku/cplib/tree/main/src/cplib/collections/avlset.nim ImportExpand "cplib/collections/avlset" <=== "when not declared CPLIB_COLLECTIONS_AVLSET:\n const CPLIB_COLLECTIONS_AVLSET* = 1\n when not declared CPLIB_COLLECTIONS_AVLTREE:\n const CPLIB_COLLECTIONS_AVLTREE* = 1\n # 以下をNimに移植\n # https://nachiavivias.github.io/cp-library/cpp/array/bbst-list.html\n type AvlTreeNode*[K] = ref object\n l*, r*, p*: AvlTreeNode[K]\n h*, len*: int\n key*: K\n proc get_avltree_nilnode*[K](): AvlTreeNode[K] =\n let nil_node {.global.} = (block:\n var nil_node = AvlTreeNode[K](h: 0, len: 0)\n nil_node.l = nil_node\n nil_node.r = nil_node\n nil_node.p = nil_node\n nil_node\n )\n return nil_node\n proc update[K](node: AvlTreeNode[K]) =\n node.h = max(node.l.h + 1, node.r.h + 1)\n node.len = 1 + node.l.len + node.r.len\n proc set_children[K](node, l, r: AvlTreeNode[K]) =\n node.l = l\n if l != get_avltree_nilnode[K](): l.p = node\n node.r = r\n if r != get_avltree_nilnode[K](): r.p = node\n node.update()\n proc rebalance[K](node: AvlTreeNode[K]): AvlTreeNode[K] =\n var node = node\n var l = node.l\n var r = node.r\n if l.h + 1 < r.h:\n var rl = r.l\n var rr = r.r\n if rl.h <= rr.h:\n r.p = node.p\n node.set_children(l, rl)\n r.set_children(node, rr)\n return r\n else:\n rl.p = node.p\n node.set_children(l, rl.l)\n r.set_children(rl.r, rr)\n rl.set_children(node, r)\n return rl\n elif r.h + 1 < l.h:\n var ll = l.l\n var lr = l.r\n if lr.h <= ll.h:\n l.p = node.p\n node.set_children(lr, r)\n l.set_children(ll, node)\n return l\n else:\n lr.p = node.p\n node.set_children(lr.r, r)\n l.set_children(ll, lr.l)\n lr.set_children(l, node)\n return lr\n node.update\n return node\n proc rebalance_to_root[K](node: AvlTreeNode[K]): AvlTreeNode[K] =\n var node = node\n while node.p != get_avltree_nilnode[K]():\n var cp = node.p\n if cp.l == node: cp.l = node.rebalance\n else: cp.r = node.rebalance\n node = cp\n return node.rebalance\n proc rootOf*[K](node: AvlTreeNode[K]): AvlTreeNode[K] =\n result = node\n while result.p != get_avltree_nilnode[K](): result = result.p\n proc node_search[K](node: AvlTreeNode[K], key: K, strict: bool): (AvlTreeNode[K], AvlTreeNode[K]) =\n var node = node\n var result_l = get_avltree_nilnode[K]()\n var result_r = get_avltree_nilnode[K]()\n while node != get_avltree_nilnode[K]():\n if (strict and key < node.key) or (not strict and key <= node.key):\n result_r = node\n node = node.l\n else:\n result_l = node\n node = node.r\n return (result_l, result_r)\n proc lower_bound_node*[K](node: AvlTreeNode[K], key: K): (AvlTreeNode[K], AvlTreeNode[K]) = node_search[K](node, key, false)\n proc upper_bound_node*[K](node: AvlTreeNode[K], key: K): (AvlTreeNode[K], AvlTreeNode[K]) = node_search[K](node, key, true)\n proc insert*[K](node, x: AvlTreeNode[K]): AvlTreeNode[K] =\n if node == get_avltree_nilnode[K](): return x\n var (ql, qr) = node.lower_bound_node(x.key)\n if ql != get_avltree_nilnode[K]() and ql.r == get_avltree_nilnode[K]():\n ql.set_children(ql.l, x)\n return ql.rebalance_to_root\n qr.set_children(x, qr.r)\n return qr.rebalance_to_root\n proc erase*[K](node, x, nxt: AvlTreeNode[K]): AvlTreeNode[K] =\n var xp = x.p\n result = get_avltree_nilnode[K]()\n if x.r == get_avltree_nilnode[K]():\n var xl = x.l\n if xl != get_avltree_nilnode[K](): xl.p = xp\n if xp != get_avltree_nilnode[K]():\n if xp.l == x: xp.l = xl\n else: xp.r = xl\n if xp == get_avltree_nilnode[K](): result = xl\n else: result = xp.rebalance_to_root\n else:\n var nxtp = nxt.p\n var nxtr = nxt.r\n if xp != get_avltree_nilnode[K]():\n if xp.l == x: xp.l = nxt\n else: xp.r = nxt\n nxt.p = xp\n nxt.l = x.l\n if nxt.l != get_avltree_nilnode[K](): nxt.l.p = nxt\n if x.r == nxt:\n nxt.update\n result = nxt.rebalance_to_root\n else:\n if nxtp.l == nxt: nxtp.l = nxtr\n else: nxtp.r = nxtr\n if nxtr != get_avltree_nilnode[K](): nxtr.p = nxtp\n nxt.r = x.r\n nxt.r.p = nxt\n nxt.update\n result = nxtp.rebalance_to_root\n x.l = get_avltree_nilnode[K]()\n x.r = get_avltree_nilnode[K]()\n x.p = get_avltree_nilnode[K]()\n x.update\n proc next*[K](node: AvlTreeNode[K]): AvlTreeNode[K] =\n var node = node\n if node.r != get_avltree_nilnode[K]():\n node = node.r\n while node.l != get_avltree_nilnode[K](): node = node.l\n return node\n while node.p.r == node: node = node.p\n return node.p\n proc prev*[K](node: AvlTreeNode[K]): AvlTreeNode[K] =\n var node = node\n if node.l != get_avltree_nilnode[K]():\n node = node.l\n while node.r != get_avltree_nilnode[K](): node = node.r\n return node\n while node.p.l == node: node = node.p\n return node.p\n proc get*[K](node: AvlTreeNode[K], idx: int): AvlTreeNode[K] =\n assert idx >= 0\n if idx >= node.len: return get_avltree_nilnode[K]()\n result = node\n var idx = idx\n while result.l.len != idx:\n if result.l.len < idx:\n idx -= result.l.len + 1\n result = result.r\n else:\n result = result.l\n proc index*[K](node: AvlTreeNode[K]): int =\n var node = node\n if node == get_avltree_nilnode[K](): return 0\n result = node.l.len\n while node.p != get_avltree_nilnode[K]():\n if node.p.r == node: result += node.p.l.len + 1\n node = node.p\n \n \n import options\n import sequtils\n import strutils\n\n type AvlSortedMultiSet*[T] = object\n root*: AvlTreeNode[T]\n\n proc len*[T](self: AvlSortedMultiSet[T]): int = self.root.len\n proc lowerBound*[T](self: AvlSortedMultiSet[T], x: T): int =\n var (ql, qr) = self.root.lower_bound_node(x)\n if qr == get_avltree_nilnode[T](): return self.len\n return qr.index\n proc index*[T](self: AvlSortedMultiSet[T], x: T): int = self.lowerBound(x)\n proc upperBound*[T](self: AvlSortedMultiSet[T], x: T): int =\n var (ql, qr) = self.root.upper_bound_node(x)\n if qr == get_avltree_nilnode[T](): return self.len\n return qr.index\n proc index_right*[T](self: AvlSortedMultiSet[T], x: T): int = self.upperBound(x)\n proc count*[T](self: AvlSortedMultiSet[T], x: T): int = self.upperBound(x) - self.lowerBound(x)\n proc newnode[T](x: T): AvlTreeNode[T] =\n var nil_node = get_avltree_nilnode[T]()\n return AvlTreeNode[T](p: nil_node, l: nil_node, r: nil_node, len: 1, h: 1, key: x)\n proc lt*[T](self: AvlSortedMultiSet[T], x: T): Option[T] =\n var (node, _) = self.root.lower_bound_node(x)\n if node == get_avltree_nilnode[T](): return none(T)\n return some(node.key)\n proc le*[T](self: AvlSortedMultiSet[T], x: T): Option[T] =\n var (node, _) = self.root.upper_bound_node(x)\n if node == get_avltree_nilnode[T](): return none(T)\n return some(node.key)\n proc gt*[T](self: AvlSortedMultiSet[T], x: T): Option[T] =\n var (_, node) = self.root.upper_bound_node(x)\n if node == get_avltree_nilnode[T](): return none(T)\n return some(node.key)\n proc ge*[T](self: AvlSortedMultiSet[T], x: T): Option[T] =\n var (_, node) = self.root.lower_bound_node(x)\n if node == get_avltree_nilnode[T](): return none(T)\n return some(node.key)\n proc contains*[T](self: AvlSortedMultiSet[T], x: T): bool =\n var (_, node) = self.root.lower_bound_node(x)\n return node != get_avltree_nilnode[T]() and node.key == x\n proc incl*[T](self: var AvlSortedMultiSet[T], x: T) =\n var node = newnode(x)\n self.root = self.root.insert(node)\n proc excl*[T](self: var AvlSortedMultiSet[T], x: T): bool {.discardable.} =\n if x notin self: return false\n var (_, node) = self.root.lower_bound_node(x)\n self.root = self.root.erase(node, node.next)\n return true\n proc `[]`*[T](self: AvlSortedMultiSet[T], idx: int): T =\n assert idx < self.root.len\n return self.root.get(idx).key\n proc `[]`*[T](self: AvlSortedMultiSet[T], idx: BackwardsIndex): T =\n var idx = self.len - int(idx)\n return self[idx]\n proc pop*[T](self: var AvlSortedMultiSet[T], idx: int = -1): T =\n var idx = idx\n if idx < 0: idx = self.len + idx\n assert idx < self.root.len\n var node = self.root.get(idx)\n result = node.key\n self.root = self.root.erase(node, node.next)\n iterator items*[T](self: AvlSortedMultiSet[T]): T =\n var stack = @[(0, self.root)]\n while stack.len > 0:\n var (t, node) = stack.pop\n if t == 0:\n stack.add((1, node))\n if node.l != get_avltree_nilnode[T](): stack.add((0, node.l))\n elif t == 1:\n yield node.key\n if node.r != get_avltree_nilnode[T](): stack.add((0, node.r))\n proc `$`*[T](self: AvlSortedMultiSet[T]): string = self.toSeq.join(\" \")\n proc initAvlSortedMultiSet*[T](v: seq[T] = @[]): AvlSortedMultiSet[T] =\n result = AvlSortedMultiSet[T](root: get_avltree_nilnode[T]())\n for item in v: result.incl(item)\n" # {.checks: off.} var n = input(int) var lr = newSeqWith(n, input(int, int)).sortedByIt(it[1]) var st = initAvlSortedMultiSet[int]() for i in 0..<n: var (l, r) = lr[i] var p = st.upper_bound(l) debug(l, r, p) if p == 0: st.incl(r) else: discard st.pop(p-1) st.incl(r) print(st.len - 1)