結果
問題 | No.2065 Sum of Min |
ユーザー |
|
提出日時 | 2024-11-25 00:52:55 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,565 ms / 2,000 ms |
コード長 | 3,431 bytes |
コンパイル時間 | 353 ms |
コンパイル使用メモリ | 82,272 KB |
実行使用メモリ | 166,436 KB |
最終ジャッジ日時 | 2024-11-25 00:53:23 |
合計ジャッジ時間 | 25,860 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 20 |
ソースコード
## https://yukicoder.me/problems/no/443class SegmentTree:"""非再帰版セグメント木。更新は「加法」、取得は「最大値」のもの限定。"""def __init__(self, init_array):n = 1while n < len(init_array):n *= 2self.size = nself.array = [[] for _ in range(2 * self.size)]self.cum_array = [[] for _ in range(2 * self.size)]for i, a in enumerate(init_array):self.array[self.size + i].append(a)end_index = self.sizestart_index = end_index // 2while start_index >= 1:for i in range(start_index, end_index):self._op(self.array[i], self.array[2 * i], self.array[2 * i + 1])end_index = start_indexstart_index = end_index // 2for i in range(1, len(self.array)):c = 0for j in range(len(self.array[i])):c += self.array[i][j]self.cum_array[i].append(c)def _op(self, array, left, right):left_index = 0right_index = 0while left_index < len(left) or right_index < len(right):if left_index == len(left):while right_index < len(right):array.append(right[right_index])right_index += 1elif right_index == len(right):while left_index < len(left):array.append(left[left_index])left_index += 1else:if left[left_index] <= right[right_index]:array.append(left[left_index])left_index += 1else:array.append(right[right_index])right_index += 1def add(self, x, a):index = self.size + xself.array[index] += awhile index > 1:index //= 2self.array[index] = max(self.array[2 * index], self.array[2 * index + 1])def _calc_value(self, array, cum_array, x):if len(array) == 0:return 0if x < array[0]:return x * len(array)low = 0high = len(array) - 1while high - low > 1:mid = (high + low) // 2if array[mid] <= x:low = midelse:high = midif array[high] <= x:return cum_array[high] + x * (len(array) - 1 - high)else:return cum_array[low] + x * (len(array) - 1 - low)def get_sum(self, l, r, x):L = self.size + l; R = self.size + r# 2. 区間[l, r)の最大値を求めるs = 0while L < R:if R & 1:R -= 1s += self._calc_value(self.array[R], self.cum_array[R], x)if L & 1:s += self._calc_value(self.array[L], self.cum_array[L], x)L += 1L >>= 1; R >>= 1return sdef main():N, Q = map(int, input().split())A = list(map(int, input().split()))lrx = []for _ in range(Q):l, r, x = map(int, input().split())lrx.append((l - 1, r - 1, x))seg_tree = SegmentTree(A)for l, r, x in lrx:ans = seg_tree.get_sum(l, r + 1, x)print(ans)if __name__ == "__main__":main()