結果
| 問題 | No.879 Range Mod 2 Query |
| コンテスト | |
| ユーザー |
maspy
|
| 提出日時 | 2020-04-30 17:18:38 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,583 bytes |
| 記録 | |
| コンパイル時間 | 358 ms |
| コンパイル使用メモリ | 82,176 KB |
| 実行使用メモリ | 193,784 KB |
| 最終ジャッジ日時 | 2024-12-16 04:40:30 |
| 合計ジャッジ時間 | 25,397 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | WA * 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)
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])
def _propagate_at(self, i):
if self.A[i] == self.A_unit:
return
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 n in range(h, 0, -1):
self._propagate_at(i >> n)
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)
vL = vR = self.X_unit
while L < R:
if L & 1:
vL = self.X_f(vL, self._eval_at(L))
L += 1
if R & 1:
R -= 1
vR = self.X_f(self._eval_at(R), vR)
L >>= 1
R >>= 1
return self.X_f(vL, vR)
X_unit = (0, 0, 0) # even, odd, sum
A_unit = (2, 0)
def X_f(x, y):
return (x[0] + y[0], x[1] + y[1], x[2] + y[2])
def A_f(x, y):
if y[0] <= 1:
return ((x[0] + x[1] + y[0]) & 1, y[1])
return (x[0], x[1] + y[1])
def operate(x, a):
ev, od, su = x
t, add = a
if t == 2:
if add & 1:
return (od, ev, su + add * (ev + od))
return (ev, od, su + add * (ev + od))
if t == 1:
ev, od = od, ev
su = od + add * (ev + od)
if add & 1:
ev, od = od, ev
return (ev, od, su)
N, Q = map(int, readline().split())
seg = LazySegTree(N, X_f, X_unit, A_f, A_unit, operate)
A = map(int, readline().split())
A = ((0, 1, x) if x & 1 else (1, 0, x) 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, 0))
elif query.startswith(b'2'):
L, R, x = map(int, query[2:].split())
seg.operate_range(L - 1, R, (2, x))
elif query.startswith(b'3'):
L, R = map(int, query[2:].split())
print(seg.fold(L - 1, R)[2])
maspy