結果
問題 | No.1099 Range Square Sum |
ユーザー | tktk_snsn |
提出日時 | 2020-12-15 20:50:33 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,927 ms / 2,000 ms |
コード長 | 3,933 bytes |
コンパイル時間 | 151 ms |
コンパイル使用メモリ | 81,920 KB |
実行使用メモリ | 230,368 KB |
最終ジャッジ日時 | 2024-09-20 02:10:16 |
合計ジャッジ時間 | 16,847 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 38 ms
52,992 KB |
testcase_01 | AC | 37 ms
52,864 KB |
testcase_02 | AC | 40 ms
52,992 KB |
testcase_03 | AC | 39 ms
52,736 KB |
testcase_04 | AC | 39 ms
52,608 KB |
testcase_05 | AC | 39 ms
53,248 KB |
testcase_06 | AC | 39 ms
52,992 KB |
testcase_07 | AC | 40 ms
52,864 KB |
testcase_08 | AC | 38 ms
52,992 KB |
testcase_09 | AC | 38 ms
52,992 KB |
testcase_10 | AC | 38 ms
53,376 KB |
testcase_11 | AC | 125 ms
77,932 KB |
testcase_12 | AC | 116 ms
76,552 KB |
testcase_13 | AC | 130 ms
77,196 KB |
testcase_14 | AC | 123 ms
77,472 KB |
testcase_15 | AC | 119 ms
76,912 KB |
testcase_16 | AC | 125 ms
77,588 KB |
testcase_17 | AC | 124 ms
77,440 KB |
testcase_18 | AC | 121 ms
76,928 KB |
testcase_19 | AC | 133 ms
77,208 KB |
testcase_20 | AC | 125 ms
76,816 KB |
testcase_21 | AC | 1,711 ms
229,380 KB |
testcase_22 | AC | 1,896 ms
229,924 KB |
testcase_23 | AC | 1,738 ms
229,592 KB |
testcase_24 | AC | 1,927 ms
230,368 KB |
testcase_25 | AC | 1,737 ms
229,440 KB |
testcase_26 | AC | 898 ms
147,056 KB |
testcase_27 | AC | 872 ms
146,536 KB |
testcase_28 | AC | 888 ms
147,308 KB |
testcase_29 | AC | 927 ms
147,512 KB |
testcase_30 | AC | 917 ms
148,336 KB |
ソースコード
class LazySegmetTree: def __init__(self, size, op_data, u_data, op_lazy, u_lazy, op_merge): """ size: 元の配列の長さ op_data(Ldata, Rdata), u_data: クエリ関数、単位元 op_lazy(Llazy, Rlazy), u_lazy: 遅延作用の関数、単位元 op_merge(lazy, data): dataとlazyとの演算 """ self.N = size self.op_data = op_data self.op_lazy = op_lazy self.op_merge = op_merge self.u_data = u_data self.u_lazy = u_lazy self.data = [u_data] * (2 * self.N) self.lazy = [u_lazy] * (2 * self.N) def initialize(self, arr): op = self.op_data for i, a in enumerate(arr, self.N): self.data[i] = a for i in reversed(range(1, self.N)): self.data[i] = op(self.data[i << 1], self.data[i << 1 | 1]) def show(self): print("show array") for i in range(self.N): print(self.fold(i, i+1), end=" ") print("\n") def _propagate_top_down(self, L): op = self.op_lazy merge = self.op_merge unit = self.u_lazy for i in reversed(range(1, L.bit_length())): i = L >> i v = self.lazy[i] if v == unit: continue self.data[i] = merge(v, self.data[i]) self.lazy[i << 1] = op(v, self.lazy[i << 1]) self.lazy[i << 1 | 1] = op(v, self.lazy[i << 1 | 1]) self.lazy[i] = unit def _propagate_bottom_up(self, i): merge = self.op_merge op = self.op_data while i > 1: i >>= 1 self.data[i] = op(merge(self.lazy[i << 1], self.data[i << 1]), merge(self.lazy[i << 1 | 1], self.data[i << 1 | 1])) def fold(self, L, R): resL = self.u_data resR = self.u_data op = self.op_data merge = self.op_merge L += self.N R += self.N L0 = L // (L & -L) R0 = R // (R & -R) - 1 self._propagate_top_down(L0) self._propagate_top_down(R0) while L < R: if L & 1: resL = op(resL, merge(self.lazy[L], self.data[L])) L += 1 if R & 1: R -= 1 resR = op(merge(self.lazy[R], self.data[R]), resR) L >>= 1 R >>= 1 return op(resL, resR) def update(self, i, val): # 未調整 i += self.N i0 = i // (i & -i) self._propagate_top_down(i0) self.data[i] = self.op_merge(self.lazy[i], self.data[i]) self.data[i] = self.op_data(val, self.data[i]) self.lazy[i] = self.u_lazy self._propagate_bottom_up(i0) def range_update(self, L, R, val): op = self.op_lazy L += self.N R += self.N L0 = L // (L & -L) R0 = R // (R & -R) - 1 self._propagate_top_down(L0) self._propagate_top_down(R0) while L < R: if L & 1: self.lazy[L] = op(val, self.lazy[L]) L += 1 if R & 1: R -= 1 self.lazy[R] = op(val, self.lazy[R]) L >>= 1 R >>= 1 self._propagate_bottom_up(L0) self._propagate_bottom_up(R0) u_data = (0, 0, 0) # size, sum, sqsum u_lazy = 0 def op_data(l, r): return l[0]+r[0], l[1]+r[1], l[2]+r[2] def op_lazy(a, b): return a + b def op_merge(lz, d): return d[0], d[1] + d[0] * lz, d[2] + (2 * d[1] + d[0] * lz) * lz N = int(input()) A = tuple(map(int, input().split())) seg = LazySegmetTree(N, op_data, u_data, op_lazy, u_lazy, op_merge) seg.initialize([(1, a, a * a) for a in A]) Q = int(input()) for _ in range(Q): k, *arg = map(int, input().split()) if k == 1: l, r, x = arg seg.range_update(l - 1, r, x) else: l, r = arg print(seg.fold(l - 1, r)[2])