結果
| 問題 | No.879 Range Mod 2 Query |
| コンテスト | |
| ユーザー |
maspy
|
| 提出日時 | 2020-04-30 19:50:39 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,751 ms / 3,000 ms |
| コード長 | 3,754 bytes |
| 記録 | |
| コンパイル時間 | 148 ms |
| コンパイル使用メモリ | 82,284 KB |
| 実行使用メモリ | 117,500 KB |
| 最終ジャッジ日時 | 2024-12-17 13:14:46 |
| 合計ジャッジ時間 | 20,235 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 21 |
ソースコード
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
class LazySegTree:
def __init__(self, N, X_f, X_unit, A_f, A_unit, operate):
self.N = N
self.X_f = X_f
self.X_unit = X_unit
self.A_f = A_f
self.A_unit = A_unit
self.operate = operate
self.X = [self.X_unit] * (N + N)
self.A = [self.A_unit] * (N + N)
self.N_elem = [0] * (N+N)
for i in range(N, N+N):
self.N_elem[i] = 1
for i in range(N-1, 0, -1):
self.N_elem[i] = self.N_elem[i<<1] + self.N_elem[i<<1|1]
def build(self, seq):
for i, x in enumerate(seq, N):
self.X[i] = x
for i in range(N - 1, 0, -1):
self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1])
def _eval_at(self, i):
return self.operate(self.X[i], self.A[i], self.N_elem[i])
def _propagate_at(self, i):
self.X[i] = self._eval_at(i)
self.A[i << 1] = self.A_f(self.A[i << 1], self.A[i])
self.A[i << 1 | 1] = self.A_f(self.A[i << 1 | 1], self.A[i])
self.A[i] = self.A_unit
def _propagate_above(self, i):
H = i.bit_length() - 1
for h in range(H, 0, -1):
self._propagate_at(i >> h)
def _recalc_above(self, i):
while i > 1:
i >>= 1
self.X[i] = self.X_f(self._eval_at(i << 1),
self._eval_at(i << 1 | 1))
def set_val(self, i, x):
i += self.N
self._propagate_above(i)
self.X[i] = x
self.A[i] = self.A_unit
self._recalc_above(i)
def operate_range(self, L, R, x):
L += self.N
R += self.N
L0 = L // (L & -L)
R0 = R // (R & -R) - 1
self._propagate_above(L0)
self._propagate_above(R0)
while L < R:
if L & 1:
self.A[L] = self.A_f(self.A[L], x)
L += 1
if R & 1:
R -= 1
self.A[R] = self.A_f(self.A[R], x)
L >>= 1
R >>= 1
self._recalc_above(L0)
self._recalc_above(R0)
def fold(self, L, R):
L += self.N
R += self.N
self._propagate_above(L // (L & -L))
self._propagate_above(R // (R & -R) - 1)
v = self.X_unit
while L < R:
if L & 1:
v = self.X_f(v, self._eval_at(L))
L += 1
if R & 1:
R -= 1
v = self.X_f(self._eval_at(R), v)
L >>= 1
R >>= 1
return v
X_unit = 0 # odd + (sum << 20)
A_unit = 2
def X_f(x, y):
return x + y
def A_f(x, y):
x1, x0 = divmod(x, 3)
y1, y0 = divmod(y, 3)
if y0 != 2:
return 3 * y1 + ((x0 + x1 + y0) & 1)
return 3 * (x1 + y1) + x0
def operate(x, a, n):
mask = (1<<20) - 1
od = x & mask
su = x >> 20
add, t = divmod(a, 3)
if t == 2:
if add & 1:
od = n - od
return od + (su + add * n << 20)
if t == 1:
od = n - od
su = od + add * n
if add & 1:
od = n - od
return od + (su << 20)
N, Q = map(int, readline().split())
seg = LazySegTree(N, X_f, X_unit, A_f, A_unit, operate)
A = map(int, readline().split())
A = ((x << 20) + (x & 1) for x in A)
seg.build(A)
for query in readlines():
if query.startswith(b'1'):
L, R = map(int, query[2:].split())
seg.operate_range(L - 1, R, 0)
elif query.startswith(b'2'):
L, R, x = map(int, query[2:].split())
seg.operate_range(L - 1, R, 3 * x + 2)
elif query.startswith(b'3'):
L, R = map(int, query[2:].split())
print(seg.fold(L - 1, R) >> 20)
maspy