結果
| 問題 |
No.2498 OX Operations
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-10-05 09:59:16 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 2,898 ms / 4,000 ms |
| コード長 | 3,459 bytes |
| コンパイル時間 | 342 ms |
| コンパイル使用メモリ | 82,048 KB |
| 実行使用メモリ | 102,272 KB |
| 最終ジャッジ日時 | 2024-07-26 14:59:53 |
| 合計ジャッジ時間 | 27,889 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 23 |
ソースコード
import sys
def popcount(n):
c = (n & 0x5555555555555555) + ((n >> 1) & 0x5555555555555555)
c = (c & 0x3333333333333333) + ((c >> 2) & 0x3333333333333333)
c = (c & 0x0F0F0F0F0F0F0F0F) + ((c >> 4) & 0x0F0F0F0F0F0F0F0F)
c = (c & 0x00FF00FF00FF00FF) + ((c >> 8) & 0x00FF00FF00FF00FF)
c = (c & 0x0000FFFF0000FFFF) + ((c >> 16) & 0x0000FFFF0000FFFF)
c = (c & 0x00000000FFFFFFFF) + ((c >> 32) & 0x00000000FFFFFFFF)
return c
class DualSegTree:
def __init__(self, n, comp, id):
self.n = n
self.comp = comp
self.id = id
self.sz = 1
self.log = 0
while self.sz < n:
self.sz <<= 1
self.log += 1
self.lz = [id] * (self.sz * 2)
def push(self, p):
self.lz[p << 1] = self.comp(self.lz[p], self.lz[p << 1])
self.lz[(p << 1) + 1] = self.comp(self.lz[p], self.lz[(p << 1) + 1])
self.lz[p] = self.id
def push_all(self, p):
for i in range(self.log, 0, -1):
self.push(p >> i)
def get(self, p):
P = p + self.sz
self.push_all(P)
return self.lz[P]
def set(self, p, f):
P = p + self.sz
self.push_all(P)
self.lz[P] = f
def apply(self, l, r, f):
if l >= r:
return
L = l + self.sz
R = r + self.sz
for i in range(self.log, 0, -1):
if ((L >> i) << i) != L:
self.push(L >> i)
if ((R >> i) << i) != R:
self.push((R - 1) >> i)
while L < R:
if L & 1:
self.lz[L] = self.comp(f, self.lz[L])
L += 1
if R & 1:
R -= 1
self.lz[R] = self.comp(f, self.lz[R])
L >>= 1
R >>= 1
LOG = 30
MASK = (1 << LOG) - 1
MOD = 998244353
def comp(f, g):
return ((~g[0] & f[0]) | (g[0] & f[1]), (~g[1] & f[0]) | (g[1] & f[1]))
id = (0, MASK)
s = input().split(" ")
n = int(s[0])
q = int(s[1])
m = list(map(int, input().split()))
seg = DualSegTree(n, comp, id)
for i in range(q):
s = input().split(" ")
l = int(s[1]) - 1
r = int(s[2])
x = int(s[3])
seg.apply(l, r, (x, MASK if s[0] == "o" else MASK ^ x))
fact = [1] * 100
ifact = [1] * 100
for i in range(1, 100):
fact[i] = fact[i - 1] * i % MOD
ifact[99] = pow(fact[99], MOD - 2, MOD)
for i in range(99, 0, -1):
ifact[i - 1] = ifact[i] * i % MOD
prod = [1] * (LOG + 1)
for p in range(n):
r = seg.get(p)
b = r[0]
c = r[1]
ma = m[p] + 1
dp = [0] * (LOG + 1)
a = 0
for k in range(LOG - 1, -1, -1):
newdp = [0] * (LOG + 1)
d = (b >> k) & 1
for i in range(d, LOG + 1):
newdp[i] += dp[i - d]
if newdp[i] >= MOD:
newdp[i] -= MOD
d = (c >> k) & 1
for i in range(d, LOG + 1):
newdp[i] += dp[i - d]
if newdp[i] >= MOD:
newdp[i] -= MOD
dp = newdp
a += (b >> k) & 1
if (ma >> k) & 1:
dp[a] += 1
if dp[a] >= MOD:
dp[a] -= MOD
a += ((c >> k) & 1) - ((b >> k) & 1)
for i in range(LOG):
dp[i + 1] += dp[i]
if dp[i + 1] >= MOD:
dp[i + 1] -= MOD
for i in range(LOG + 1):
prod[i] = prod[i] * dp[i] % MOD
ans = LOG * prod[LOG] % MOD
for i in range(LOG):
ans -= prod[i]
if ans < 0:
ans += MOD
print(ans)