結果
| 問題 | No.875 Range Mindex Query |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-06-10 16:44:43 |
| 言語 | Crystal (1.14.0) |
| 結果 |
AC
|
| 実行時間 | 252 ms / 2,000 ms |
| コード長 | 2,120 bytes |
| コンパイル時間 | 12,877 ms |
| コンパイル使用メモリ | 312,872 KB |
| 実行使用メモリ | 17,792 KB |
| 最終ジャッジ日時 | 2025-01-02 09:44:50 |
| 合計ジャッジ時間 | 15,555 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
ソースコード
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