結果

問題 No.875 Range Mindex Query
ユーザー yukimyyukimy
提出日時 2024-06-10 16:44:43
言語 Crystal
(1.11.2)
結果
AC  
実行時間 226 ms / 2,000 ms
コード長 2,120 bytes
コンパイル時間 14,016 ms
コンパイル使用メモリ 295,384 KB
実行使用メモリ 21,080 KB
最終ジャッジ日時 2024-06-10 16:45:00
合計ジャッジ時間 13,540 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,812 KB
testcase_01 AC 3 ms
6,812 KB
testcase_02 AC 3 ms
6,820 KB
testcase_03 AC 2 ms
6,944 KB
testcase_04 AC 2 ms
6,940 KB
testcase_05 AC 2 ms
6,944 KB
testcase_06 AC 2 ms
6,944 KB
testcase_07 AC 2 ms
6,940 KB
testcase_08 AC 2 ms
6,944 KB
testcase_09 AC 2 ms
6,940 KB
testcase_10 AC 3 ms
6,944 KB
testcase_11 AC 143 ms
17,412 KB
testcase_12 AC 116 ms
11,412 KB
testcase_13 AC 104 ms
20,896 KB
testcase_14 AC 97 ms
16,900 KB
testcase_15 AC 141 ms
21,056 KB
testcase_16 AC 217 ms
21,008 KB
testcase_17 AC 226 ms
21,080 KB
testcase_18 AC 208 ms
21,012 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

class SegmentTree(T)
  @sz : Int64
  #配列、単位元、比較用の演算をブロックで渡す
  def initialize(ary : Array(T), @defv : T, &block : T, T -> T)
    n = ary.size.to_i64
    sz = 1_i64
    while sz < n
      sz *= 2
    end
    @tree = Array(T).new(sz*2-1,@defv)
    @sz = sz
    @compare_proc = block
    i = 0
    #葉に元の値を入れる
    while i < n
      @tree[i+sz-1] = ary[i]
      i += 1
    end
    i = sz - 2
    while i >= 0
      #親に上って子を比較しながら値を入れる
      @tree[i] = @compare_proc.call(@tree[i*2+1], @tree[i*2+2])
      i -= 1
    end
  end

  #全ての葉を返す
  def tree
    @tree[@sz-1..-1]
  end

  #indexを指定して値を返す
  def [] (i : Int64)
    i += @sz - 1
    @tree[i]
  end

  #数値による置換
  def update(i : Int64, val : T)
    i += @sz - 1
    #葉を更新する
    @tree[i] = val
    while i > 0
      i = (i-1) // 2
      #親に上って更新する
      @tree[i] = @compare_proc.call(@tree[i*2+1], @tree[i*2+2])
    end
  end

  #ブロックによる置換
  def update(i : Int64)
    i += @sz - 1
    #葉を更新する
    @tree[i] = yield(@tree[i])
    while i > 0
      i = (i-1) // 2
      #親に上って更新する
      @tree[i] = @compare_proc.call(@tree[i*2+1], @tree[i*2+2])
    end
  end

  #特定区間の演算結果を返す
  def get(a : Int64, b : Int64, now = 0_i64, l = 0_i64, r = -1_i64)
    r = @sz if r < 0
    return @defv if (b <= l || r <= a)
    return @tree[now] if (a <= l && r <= b)
    vl = get(a,b,now*2+1,l,(l+r)//2)
    vr = get(a,b,now*2+2,(l+r)//2,r)
    return @compare_proc.call(vl, vr)
  end    
end

n, q = read_line.split.map(&.to_i64)
a = read_line.split.map(&.to_i64)
inf = 10_i64 ** 18
tree = SegmentTree(Tuple(Int64, Int64)).new(a.map_with_index { |v, i| {v, i.to_i64} }, {inf, -1_i64}) { |a, b| a[0] < b[0] ? a : b }
q.times do
  t, l, r = read_line.split.map(&.to_i64)
  if t == 1
    al = tree[l - 1][0]
    ar = tree[r - 1][0]
    tree.update(r - 1, {al, r - 1})
    tree.update(l - 1, {ar, l - 1})
  else
    puts tree.get(l - 1, r)[1] + 1
  end
end
0