結果
問題 | No.877 Range ReLU Query |
ユーザー | kept1994 |
提出日時 | 2022-01-06 02:51:56 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,142 ms / 2,000 ms |
コード長 | 2,919 bytes |
コンパイル時間 | 555 ms |
コンパイル使用メモリ | 81,792 KB |
実行使用メモリ | 131,964 KB |
最終ジャッジ日時 | 2024-11-08 10:39:42 |
合計ジャッジ時間 | 13,174 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 50 ms
60,544 KB |
testcase_01 | AC | 97 ms
81,920 KB |
testcase_02 | AC | 89 ms
79,744 KB |
testcase_03 | AC | 109 ms
84,992 KB |
testcase_04 | AC | 58 ms
68,224 KB |
testcase_05 | AC | 81 ms
75,904 KB |
testcase_06 | AC | 81 ms
76,544 KB |
testcase_07 | AC | 75 ms
73,856 KB |
testcase_08 | AC | 114 ms
84,864 KB |
testcase_09 | AC | 60 ms
68,480 KB |
testcase_10 | AC | 91 ms
80,640 KB |
testcase_11 | AC | 1,045 ms
127,744 KB |
testcase_12 | AC | 964 ms
123,256 KB |
testcase_13 | AC | 774 ms
116,524 KB |
testcase_14 | AC | 795 ms
116,828 KB |
testcase_15 | AC | 1,142 ms
130,612 KB |
testcase_16 | AC | 1,102 ms
128,040 KB |
testcase_17 | AC | 1,129 ms
130,372 KB |
testcase_18 | AC | 1,091 ms
128,776 KB |
testcase_19 | AC | 1,026 ms
131,520 KB |
testcase_20 | AC | 1,121 ms
131,964 KB |
ソースコード
#!/usr/bin/env python3 class SegmentTree: def __init__(self, monoid: int, bottomLen: int, operation: "function"): self.monoid = monoid self.bottomLen = bottomLen self.offset = self.bottomLen # セグ木の最下層の最初のインデックスに合わせるためのオフセット self.segLen = self.bottomLen * 2 self.tree = [monoid] * self.segLen self.operation = operation return """ 1点更新 O(1) """ def pointUpdateWithoutRebuild(self, index: int, val: int): segIndex = index + self.offset self.tree[segIndex] += val # 各マスの更新方法 return """ 全区間更新 O(bottomLen) # =セグ木の配列長 """ def allBuild(self): for segIndex in reversed(range(self.offset)): if segIndex == 0: return self.tree[segIndex] = self.operation(self.tree[segIndex * 2], self.tree[segIndex * 2 + 1]) return """ 1点更新 + リビルド O(log(bottomLen)) """ def pointUpdate(self, index: int, val: int): segIndex = index + self.offset self.tree[segIndex] += val # 各マスの更新方法 while True: segIndex //= 2 if segIndex == 0: break self.tree[segIndex] = self.operation(self.tree[segIndex * 2], self.tree[segIndex * 2 + 1]) return def rangeQuery(self, l: int, r: int): l += self.offset r += self.offset res = self.monoid # クエリの初期値 while l < r: if l % 2 == 1: res = self.operation(res, self.tree[l]) l += 1 l //= 2 if r % 2 == 1: res = self.operation(res, self.tree[r - 1]) r -= 1 r //= 2 return res def add(a: int, b: int): return a + b def main(): N, Q = map(int, input().split()) A = list(map(int, input().split())) queries = [] qq = [] for i in range(N): qq.append((A[i], i, 0)) tr = SegmentTree(monoid=0, bottomLen=2**18, operation=add) count = SegmentTree(monoid=0, bottomLen=2**18, operation=add) for i in range(Q): query = list(map(int, input().split())) queries.append(query) qq.append((query[-1], i, 1)) qq.sort() ans = [-1] * Q # print(qq) for qqq in qq[::-1]: # print(qqq) if qqq[2] == 0: tr.pointUpdate(qqq[1], qqq[0]) count.pointUpdate(qqq[1], 1) else: num = tr.rangeQuery(queries[qqq[1]][1] - 1, queries[qqq[1]][2]) c = count.rangeQuery(queries[qqq[1]][1] - 1, queries[qqq[1]][2]) ans[qqq[1]] = num - c * queries[qqq[1]][3] # print(tr.tree) print(*ans, sep="\n") return if __name__ == '__main__': main()