結果

問題 No.3094 Stapler
ユーザー kemuniku
提出日時 2025-04-06 18:19:49
言語 Nim
(2.2.0)
結果
AC  
実行時間 210 ms / 2,000 ms
コード長 13,037 bytes
コンパイル時間 4,043 ms
コンパイル使用メモリ 78,936 KB
実行使用メモリ 68,396 KB
最終ジャッジ日時 2025-06-20 02:32:18
合計ジャッジ時間 15,527 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 72
権限があれば一括ダウンロードができます

ソースコード

diff #

import macros;macro ImportExpand(s:untyped):untyped = parseStmt($s[2])
# source: src/cplib/tmpl/sheep.nim
ImportExpand "cplib/tmpl/sheep" <=== "when not declared CPLIB_TMPL_SHEEP:\n    const CPLIB_TMPL_SHEEP* = 1\n    {.warning[UnusedImport]: off.}\n    {.hint[XDeclaredButNotUsed]: off.}\n    import algorithm\n    import sequtils\n    import tables\n    import macros\n    import math\n    import sets\n    import strutils\n    import strformat\n    import sugar\n    import heapqueue\n    import streams\n    import deques\n    import bitops\n    import std/lenientops\n    import options\n    #入力系\n    proc scanf(formatstr: cstring){.header: \"<stdio.h>\", varargs.}\n    proc getchar(): char {.importc: \"getchar_unlocked\", header: \"<stdio.h>\", discardable.}\n    proc ii(): int {.inline.} = scanf(\"%lld\\n\", addr result)\n    proc lii(N: int): seq[int] {.inline.} = newSeqWith(N, ii())\n    proc si(): string {.inline.} =\n        result = \"\"\n        var c: char\n        while true:\n            c = getchar()\n            if c == ' ' or c == '\\n' or c == '\\255':\n                break\n            result &= c\n    #chmin,chmax\n    template `max=`(x, y) = x = max(x, y)\n    template `min=`(x, y) = x = min(x, y)\n    proc chmin[T](x: var T, y: T):bool=\n        if x > y:\n            x = y\n            return true\n        return false\n    proc chmax[T](x: var T, y: T):bool=\n        if x < y:\n            x = y\n            return true\n        return false\n    #bit演算\n    proc `%`*(x: int, y: int): 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: int, y: int): int{.inline.} =\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: var int, y: int): void = x = x%y\n    proc `//=`(x: var int, y: int): void = x = x//y\n    proc `**`(x: int, y: int): int = x^y\n    proc `**=`(x: var int, y: int): void = x = x^y\n    proc `^`(x: int, y: int): int = x xor y\n    proc `|`(x: int, y: int): int = x or y\n    proc `&`(x: int, y: int): int = x and y\n    proc `>>`(x: int, y: int): int = x shr y\n    proc `<<`(x: int, y: int): int = x shl y\n    proc `~`(x: int): int = not x\n    proc `^=`(x: var int, y: int): void = x = x ^ y\n    proc `&=`(x: var int, y: int): void = x = x & y\n    proc `|=`(x: var int, y: int): void = x = x | y\n    proc `>>=`(x: var int, y: int): void = x = x >> y\n    proc `<<=`(x: var int, y: int): void = x = x << y\n    proc `[]`(x: int, n: int): bool = (x and (1 shl n)) != 0\n    #便利な変換\n    proc `!`(x: char, a = '0'): int = int(x)-int(a)\n    #定数\n    when not declared CPLIB_UTILS_CONSTANTS:\n        const CPLIB_UTILS_CONSTANTS* = 1\n        const INF32*: int32 = 1001000027.int32\n        const INF64*: int = int(3300300300300300491)\n    \n    const INF = INF64\n    #converter\n\n    #range\n    iterator range(start: int, ends: int, step: int): int =\n        var i = start\n        if step < 0:\n            while i > ends:\n                yield i\n                i += step\n        elif step > 0:\n            while i < ends:\n                yield i\n                i += step\n    iterator range(ends: int): int = (for i in 0..<ends: yield i)\n    iterator range(start: int, ends: int): int = (for i in\n            start..<ends: yield i)\n\n    #joinが非stringでめちゃくちゃ遅いやつのパッチ\n    proc join*[T: not string](a: openArray[T], sep: string = \"\"): string = a.mapit($it).join(sep)\n\n    proc dump[T](arr:seq[seq[T]])=\n        for i in 0..<len(arr):\n            echo arr[i]\n"
# source: src/atcoder/lazysegtree.nim
ImportExpand "atcoder/lazysegtree" <=== "when not declared ATCODER_LAZYSEGTREE_HPP:\n  const ATCODER_LAZYSEGTREE_HPP* = 1\n  \n  when not declared ATCODER_INTERNAL_BITOP_HPP:\n    const ATCODER_INTERNAL_BITOP_HPP* = 1\n    import std/bitops\n  \n  #ifdef _MSC_VER\n  #include <intrin.h>\n  #endif\n  \n  # @param n `0 <= n`\n  # @return minimum non-negative `x` s.t. `n <= 2**x`\n    proc ceil_pow2*(n:SomeInteger):int =\n      var x = 0\n      while (1.uint shl x) < n.uint: x.inc\n      return x\n  # @param n `1 <= n`\n  # @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`\n    proc bsf*(n:SomeInteger):int =\n      return countTrailingZeroBits(n)\n  \n  when not declared ATCODER_RANGEUTILS_HPP:\n    const ATCODER_RANGEUTILS_HPP* = 1\n    type RangeType* = Slice[int] | HSlice[int, BackwardsIndex] | Slice[BackwardsIndex]\n    type IndexType* = int | BackwardsIndex\n    template halfOpenEndpoints*(p:Slice[int]):(int,int) = (p.a, p.b + 1)\n    template `^^`*(s, i: untyped): untyped =\n      (when i is BackwardsIndex: s.len - int(i) else: int(i))\n    template halfOpenEndpoints*[T](s:T, p:RangeType):(int,int) =\n      (s^^p.a, s^^p.b + 1)\n  \n  import std/sequtils\n  import std/algorithm\n  {.push inline.}\n  type LazySegTree*[S,F;p:static[tuple]] = object\n    len*, size*, log*:int\n    d*:seq[S]\n    lz*:seq[F]\n\n  template calc_op*[ST:LazySegTree](self:ST or typedesc[ST], a, b:ST.S):auto =\n    block:\n      let u = ST.p.op(a, b)\n      u\n  template calc_e*[ST:LazySegTree](self:ST or typedesc[ST]):auto =\n    block:\n      let u = ST.p.e()\n      u\n  template calc_mapping*[ST:LazySegTree](self:ST or typedesc[ST], a:ST.F, b:ST.S):auto =\n    block:\n      let u = ST.p.mapping(a, b)\n      u\n  template calc_composition*[ST:LazySegTree](self:ST or typedesc[ST], a, b:ST.F):auto =\n    block:\n      # こう書かないとバグる事象を検出\n      let u = ST.p.composition(a, b)\n      u\n  template calc_id*[ST:LazySegTree](self:ST or typedesc[ST]):auto =\n    block:\n      let u = ST.p.id()\n      u\n\n  proc update[ST:LazySegTree](self:var ST, k:int) =\n    self.d[k] = ST.calc_op(self.d[2 * k], self.d[2 * k + 1])\n  proc all_apply*[ST:LazySegTree](self:var ST, k:int, f:ST.F) =\n    self.d[k] = ST.calc_mapping(f, self.d[k])\n    if k < self.size:\n      self.lz[k] = ST.calc_composition(f, self.lz[k])\n  proc all_apply*[ST:LazySegTree](self:var ST, f:ST.F) =\n    self.all_apply(1, f)\n  proc push*[ST:LazySegTree](self: var ST, k:int) =\n    self.all_apply(2 * k, self.lz[k])\n    self.all_apply(2 * k + 1, self.lz[k])\n    self.lz[k] = ST.calc_id()\n\n  proc init[ST:LazySegTree](self:var ST, v:seq[ST.S]) =\n    let\n      n = v.len\n      log = ceil_pow2(n)\n      size = 1 shl log\n    (self.len, self.size, self.log) = (n, size, log)\n    if self.d.len < 2 * size:\n      self.d = newSeqWith(2 * size, ST.calc_e())\n    else:\n      self.d.fill(0, 2 * size - 1, ST.calc_e())\n    for i in 0..<n:\n      self.d[size + i] = v[i]\n    if self.lz.len < size:\n      self.lz = newSeqWith(size, ST.calc_id())\n    else:\n      self.lz.fill(0, size - 1, ST.calc_id())\n    for i in countdown(size - 1, 1): self.update(i)\n  proc init*[ST:LazySegTree](self: var ST, n:int) = self.init(newSeqWith(n, ST.calc_e()))\n  proc init*[ST:LazySegTree](self: typedesc[ST], v:seq[ST.S] or int):ST = result.init(v)\n\n  template LazySegTreeType[S, F](op0, e0, mapping0, composition0, id0:untyped):typedesc[LazySegTree] =\n    proc op1(a, b:S):S {.gensym inline.} = op0(a, b)\n    proc e1():S {.gensym inline.} = e0()\n    proc mapping1(f:F, s:S):S {.gensym inline.} = mapping0(f, s)\n    proc composition1(f1, f2:F):F {.gensym inline.} = composition0(f1, f2)\n    proc id1():F {.gensym inline.} = id0()\n    LazySegTree[S, F, (op:op1, e:e1, mapping:mapping1, composition:composition1, id:id1)]\n\n  template getType*(ST:typedesc[LazySegTree], S, F:typedesc, op, e, mapping, composition, id:untyped):typedesc[LazySegTree] =\n    LazySegTreeType[S, F](op, e, mapping, composition, id)\n\n  template initLazySegTree*[S, F](v:seq[S] or int, op, e, mapping, composition, id:untyped):auto =\n    LazySegTreeType[S, F](op, e, mapping, composition, id).init(v)\n\n  proc set*[ST:LazySegTree](self: var ST, p:IndexType, x:ST.S) =\n    var p = self^^p\n    assert p in 0..<self.len\n    p += self.size\n    for i in countdown(self.log, 1): self.push(p shr i)\n    self.d[p] = x\n    for i in 1..self.log: self.update(p shr i)\n\n  proc get*[ST:LazySegTree](self: var ST, p:IndexType):ST.S =\n    var p = self^^p\n    assert p in 0..<self.len\n    p += self.size\n    for i in countdown(self.log, 1): self.push(p shr i)\n    return self.d[p]\n\n  proc `[]=`*[ST:LazySegTree](self: var ST, p:IndexType, x:ST.S) = self.set(p, x)\n  proc `[]`*[ST:LazySegTree](self: var ST, p:IndexType):ST.S = self.get(p)\n\n  proc prod*[ST:LazySegTree](self:var ST, p:RangeType):ST.S =\n    var (l, r) = self.halfOpenEndpoints(p)\n    assert 0 <= l and l <= r and r <= self.len\n    if l == r: return ST.calc_e()\n\n    l += self.size\n    r += self.size\n\n    for i in countdown(self.log, 1):\n      if ((l shr i) shl i) != l: self.push(l shr i)\n      if ((r shr i) shl i) != r: self.push(r shr i)\n\n    var sml, smr = ST.calc_e()\n    while l < r:\n      if (l and 1) != 0: sml = ST.calc_op(sml, self.d[l]);l.inc\n      if (r and 1) != 0: r.dec;smr = ST.calc_op(self.d[r], smr)\n      l = l shr 1\n      r = r shr 1\n    return ST.calc_op(sml, smr)\n\n  proc `[]`*[ST:LazySegTree](self: var ST, p:RangeType):ST.S = self.prod(p)\n\n  proc all_prod*[ST:LazySegTree](self:ST):auto = self.d[1]\n\n  proc apply*[ST:LazySegTree](self: var ST, p:IndexType, f:ST.F) =\n    var p = self^^p\n    assert p in 0..<self.len\n    p += self.size\n    for i in countdown(self.log, 1): self.push(p shr i)\n    self.d[p] = ST.calc_mapping(f, self.d[p])\n    for i in 1..self.log: self.update(p shr i)\n  proc apply*[ST:LazySegTree](self: var ST, p:RangeType, f:ST.F) =\n    var (l, r) = self.halfOpenEndpoints(p)\n    assert 0 <= l and l <= r and r <= self.len\n    if l == r: return\n\n    l += self.size\n    r += self.size\n\n    for i in countdown(self.log, 1):\n      if ((l shr i) shl i) != l: self.push(l shr i)\n      if ((r shr i) shl i) != r: self.push((r - 1) shr i)\n\n    block:\n      var (l, r) = (l, r)\n      while l < r:\n        if (l and 1) != 0: self.all_apply(l, f);l.inc\n        if (r and 1) != 0: r.dec;self.all_apply(r, f)\n        l = l shr 1\n        r = r shr 1\n\n    for i in 1..self.log:\n      if ((l shr i) shl i) != l: self.update(l shr i)\n      if ((r shr i) shl i) != r: self.update((r - 1) shr i)\n\n#  template <bool (*g)(S)> int max_right(int l) {\n#    return max_right(l, [](S x) { return g(x); });\n#  }\n  proc max_right*[ST:LazySegTree](self:var ST, l:IndexType, g:proc(s:ST.S):bool):int =\n    var l = self^^l\n    assert l in 0..self.len\n    assert g(ST.calc_e())\n    if l == self.len: return self.len\n    l += self.size\n    for i in countdown(self.log, 1): self.push(l shr i)\n    var sm = ST.calc_e()\n    while true:\n      while l mod 2 == 0: l = l shr 1\n      if not g(ST.calc_op(sm, self.d[l])):\n        while l < self.size:\n          self.push(l)\n          l = (2 * l)\n          if g(ST.calc_op(sm, self.d[l])):\n            sm = ST.calc_op(sm, self.d[l])\n            l.inc\n        return l - self.size\n      sm = ST.calc_op(sm, self.d[l])\n      l.inc\n      if not((l and -l) != l): break\n    return self.len\n\n#  template <bool (*g)(S)> int min_left(int r) {\n#    return min_left(r, [](S x) { return g(x); });\n#  }\n  proc min_left*[ST:LazySegTree](self: var ST, r:IndexType, g:proc(s:ST.S):bool):int =\n    var r = self^^r\n    assert r in 0..self.len\n    assert(g(ST.calc_e()))\n    if r == 0: return 0\n    r += self.size\n    for i in countdown(self.log, 1): self.push((r - 1) shr i)\n    var sm = ST.calc_e()\n    while true:\n      r.dec\n      while r > 1 and r mod 2 == 1: r = r shr 1\n      if not g(ST.calc_op(self.d[r], sm)):\n        while r < self.size:\n          self.push(r)\n          r = (2 * r + 1)\n          if g(ST.calc_op(self.d[r], sm)):\n            sm = ST.calc_op(self.d[r], sm)\n            r.dec\n        return r + 1 - self.size\n      sm = ST.calc_op(self.d[r], sm)\n      if not ((r and -r) != r): break\n    return 0\n  {.pop.}\n"


proc initRangeAddRangeMinSegtree[T](v:seq[T]):auto=
    type S = (T,int)
    type F = T
    proc op(a,b:S):S=
        if a[0] == b[0]:
            return (a[0],a[1]+b[1])
        elif a[0] < b[0]:
            return a
        else:
            return b
    proc e():S=(INF,1)
    proc mapping(f:F,x:S):S=(x[0]+f,x[1])
    proc composition(f,g:F):F=f+g
    proc id():F=0
    return LazySegTree.getType(S, F, op, e, mapping, composition, id).init(v.mapit((it,1)))

var N = ii()
var Q = ii()

var st = initRangeAddRangeMinSegtree(newseqwith(N-1,0))

var querys: seq[(int,int)]

for i in range(Q):
    var T = ii()
    if T == 1:
        var L,R = ii()-1
        querys.add((L,R))
        st.apply(L..<R,1)
    elif T == 2:
        var q = ii()-1
        querys.add((-1,-1))
        var (L,R) = querys[q]
        st.apply(L..<R,-1)
    else:
        querys.add((-1,-1))
        var (a,b) = st.all_prod()
        if a == 0:
            echo b+1
        else:
            echo 1
0