結果
問題 | No.2065 Sum of Min |
ユーザー |
|
提出日時 | 2022-11-17 01:39:19 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,291 ms / 2,000 ms |
コード長 | 3,129 bytes |
コンパイル時間 | 206 ms |
コンパイル使用メモリ | 82,220 KB |
実行使用メモリ | 174,860 KB |
最終ジャッジ日時 | 2024-09-17 19:53:10 |
合計ジャッジ時間 | 23,749 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 20 |
ソースコード
#!/usr/bin/env python3class SegTree:def __init__(self, monoid, bottomList, func, convertLengthToThePowerOf2: bool = False):# print("index0 は使用されない。常にdefault値")self.monoid = monoidself.func = funcself.actualLen = len(bottomList)self.bottomLen = len(bottomList) if not convertLengthToThePowerOf2 else self.getSegLenOfThePowerOf2(len(bottomList))self.offset = self.bottomLen # セグ木の最下層の最初のインデックスに合わせるためのオフセットself.segLen = self.bottomLen * 2self.tree = [monoid] * self.segLenself.build(bottomList)"""初期化O(self.segLen)"""def build(self, seq):# 最下段の初期化for i, x in enumerate(seq, self.offset):self.tree[i] = x# ビルドfor i in range(self.offset - 1, 0, -1):self.tree[i] = self.func(self.tree[i << 1], self.tree[i << 1 | 1])"""直近の2べきの長さを算出"""def getSegLenOfThePowerOf2(self, ln: int):if ln <= 0:return 1else:import mathdecimalPart, integerPart = math.modf(math.log2(ln))return 2 ** (int(integerPart) + 1)"""一点加算O(log(self.bottomLen))"""def pointAdd(self, i: int, val: int):i += self.offsetself.tree[i] = valwhile i > 1:i >>= 1 # 2で割って頂点に達するまで下層から遡上self.tree[i] = self.func(self.tree[i << 1], self.tree[i << 1 | 1]) # 必ず末尾0と1がペアになるのでor演算子"""区間取得O(log(self.bottomLen))"""def getRange(self, l: int, r: int):l += self.offsetr += self.offsetvL = self.monoidvR = self.monoidwhile l < r:if l & 1:vL = self.func(vL, self.tree[l])l += 1if r & 1:r -= 1vR = self.func(self.tree[r], vR)l >>= 1r >>= 1return self.func(vL, vR)monoid = [0, 0]# 利用する関数を定義def add(A: int, B: int):return [A[0] + B[0], A[1] + B[1]]def main():N, Q = map(int, input().split())A = list(map(int, input().split()))queries = [(aa, 100, idx + 1, 0, 0) for idx, aa in enumerate(A)]seg = SegTree(monoid, [[0, 0] for _ in range(N)], add)for qi in range(Q):L, R, X = map(int, input().split())queries.append((X, 0, L, R, qi))queries.sort()ans = [0] * Qfor num, is_query, cidx_l, cidx_r, qi in queries:if is_query == 100:# print(cidx_l)seg.pointAdd(cidx_l - 1, [num, 1])# print(seg.tree)else:# print(seg.tree)tot, k = seg.getRange(cidx_l - 1, cidx_r)ideal = cidx_r - cidx_l + 1res = (ideal - k) * num + totans[qi] = res# print(ans)print(*ans, sep="\n")if __name__ == '__main__':main()