結果

問題 No.877 Range ReLU Query
ユーザー yukimyyukimy
提出日時 2024-06-10 18:08:23
言語 Crystal
(1.11.2)
結果
AC  
実行時間 251 ms / 2,000 ms
コード長 2,167 bytes
コンパイル時間 12,744 ms
コンパイル使用メモリ 302,936 KB
実行使用メモリ 45,952 KB
最終ジャッジ日時 2024-06-10 18:08:42
合計ジャッジ時間 17,060 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 3 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 4 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 3 ms
5,376 KB
testcase_06 AC 3 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 3 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 AC 2 ms
5,376 KB
testcase_11 AC 217 ms
37,376 KB
testcase_12 AC 196 ms
40,320 KB
testcase_13 AC 163 ms
33,024 KB
testcase_14 AC 159 ms
33,792 KB
testcase_15 AC 251 ms
45,952 KB
testcase_16 AC 228 ms
39,424 KB
testcase_17 AC 225 ms
42,240 KB
testcase_18 AC 251 ms
43,008 KB
testcase_19 AC 214 ms
38,912 KB
testcase_20 AC 242 ms
41,836 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#Binary Indexed Tree
#0~iの区間和を求める ※閉区間
class BIT
  def initialize(size : Int64)
    #1-indexにする
    @size = size + 1
    @bit = Array(Int64).new(@size,0_i64)
  end
  
  def add(i : Int64, x : Int64)
    i += 1
    while i < @size
      @bit[i] += x
      i += (i & -i)
    end
  end

  def get(i : Int64)
    i += 1
    res = 0_i64
    while i > 0
      res += @bit[i]
      i -= (i & -i)
    end
    return res
  end

  #l以上r以下(閉区間)
  def get(l : Int64, r : Int64)
    get(r) - get(l-1)
  end

  #累積和がw以上になる最小のindexを求める
  def lower_bound(w : Int64)
    return 0_i64 if w <= 0
    i = 0_i64
    r = 1_i64
    while r < n
      r <<= 1
    end
    len = r
    while len > 0
      if i + len < n && bit[i + len] < w
        w -= bit[i + len]
        i += len
      end
      len >>= 1
    end
    return i
  end
end

#座標圧縮(同値を区別しない)
def sorted_index(a : Array(Int64))
  a_size = a.size
  b = Array(Array(Int64)).new
  i = 0_i64
  while i < a_size
    b << [i,a[i]]
    i += 1
  end
  b.sort! {|v,w|v[1]<=>w[1]}
  res = Array.new(a_size,0_i64)
  i = 0_i64
  x = 0_i64
  while i < a_size
    x += 1 if i > 0 && b[i][1] != b[i-1][1]
    res[b[i][0]] = x
    i += 1
  end
  return res
end

n, q = read_line.split.map(&.to_i64)
a = read_line.split.map(&.to_i64)
tl = Array(Tuple(Int64, Int64, Int64, Int64)).new
b = Array(Int64).new
q.times do |i|
  _, l, r, x = read_line.split.map(&.to_i64)
  tl << {l - 2,  0_i64, x, i} if l != 1
  tl << {r - 1, 1_i64, x, i}
  b << x
end
c = sorted_index(a + b)
iter = Hash(Int64, Int64).new
b.each_with_index do |v, i|
  iter[v] = c[n + i]
end
m = c.max + 1
tree1 = BIT.new(m)
tree2 = BIT.new(m)
ans = Array.new(q, 0_i64)
tl.sort!
j = 0_i64
a.each_with_index do |v, i|
  tree1.add(c[i], 1_i64)
  tree2.add(c[i], v)
  while j < tl.size && tl[j][0] == i
    if tl[j][1] == 0
      ans[tl[j][3]] -= tree2.get(iter[tl[j][2]], m - 1) - tree1.get(iter[tl[j][2]], m - 1) * tl[j][2]
    else
      ans[tl[j][3]] += tree2.get(iter[tl[j][2]], m - 1) - tree1.get(iter[tl[j][2]], m - 1) * tl[j][2]
    end
    j += 1
  end
end
puts ans.join("\n")
0