結果
| 問題 |
No.3207 Digital Font
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-07-16 01:44:45 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 2,955 ms / 3,000 ms |
| コード長 | 4,400 bytes |
| コンパイル時間 | 420 ms |
| コンパイル使用メモリ | 82,340 KB |
| 実行使用メモリ | 168,144 KB |
| 最終ジャッジ日時 | 2025-07-17 07:29:49 |
| 合計ジャッジ時間 | 71,272 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 38 |
ソースコード
class SegmentTree:
def __init__(self, arr, op, e):
self.op = op
self.e = e
self.n = len(arr)
self.log = (self.n - 1).bit_length()
self.size = 1 << self.log
self.tree = [self.e for _ in range(2 * self.size)]
for i in range(self.n): self.tree[i + self.size] = arr[i]
for i in range(self.size - 1, 0, -1): self.update(i)
def update(self, i):
self.tree[i] = self.op(self.tree[2 * i + 0], self.tree[2 * i + 1])
def set(self, i, x):
i += self.size
self.tree[i] = x
i >>= 1
while i:
self.update(i)
i >>= 1
def get(self, i):
return self.tree[i + self.size]
def prod(self, l, r):
pl = self.e
pr = self.e
l += self.size
r += self.size
while l < r:
if l & 1:
pl = self.op(pl, self.tree[l])
l += 1
if r & 1:
r -= 1
pr = self.op(self.tree[r], pr)
l >>= 1
r >>= 1
return self.op(pl, pr)
def all_prod(self):
return self.tree[1]
def max_right(self, l, func):
assert(func(self.e))
if l == self.n: return self.n
l += self.size
sm = self.e
while True:
while l & 1 == 0: l >>= 1
if not func(self.op(sm, self.tree[l])):
while l < self.size:
l = 2 * l
if func(self.op(sm, self.tree[l])):
sm = self.op(sm, self.tree[l])
l += 1
return l - self.size
sm = self.op(sm, self.tree[l])
l += 1
if (l & -l) == l: break
return self.n
def min_left(self, r, func):
assert(func(self.e))
if r == 0: return 0;
r += self.size
sm = self.e
while True:
r -= 1
while r > 1 and r & 1: r >>= 1
if not func(self.op(self.tree[r], sm)):
while r < self.size:
r = 2 * r + 1
if func(self.op(self.tree[r], sm)):
sm = self.op(self.tree[r], sm)
r -= 1
return r + 1 - self.size
sm = self.op(self.tree[r], sm)
if (r & -r) == r: break
return 0
def __str__(self):
return f"SegmentTree{[self.get(i) for i in range(self.n)]}"
__repr__ = __str__
MOD = 998244353
def op(x, y):
return (x + y) % MOD
e = 0
def rectangle_sum(H, W, add, query):
N = len(add)
Q = len(query)
add.sort(key = lambda x: x[1])
qs = []
for i in range(Q):
l, d, r, u = query[i]
qs.append((l, i))
qs.append((r, i + Q))
qs.sort()
add.sort()
seg = SegmentTree([0] * W, op, e)
ans = [0] * Q
j = 0
for x, i in qs:
p = i % Q
l, d, r, u = query[p]
while j < N and add[j][0] < x:
idx = add[j][1]
seg.set(idx, (seg.get(idx) + add[j][2]) % MOD)
j += 1
if i < Q:
ans[p] -= seg.prod(d, u)
if ans[p] < 0: ans[p] += MOD
else:
ans[p] += seg.prod(d, u)
if ans[p] > MOD: ans[p] -= MOD
return ans
H, W = map(int, input().split())
N = int(input())
B1, B2 = 10007, 10009
H1, H2 = [1], [1]
for _ in range(H): H1.append((H1[-1] * B1) % MOD)
for _ in range(W): H2.append((H2[-1] * B2) % MOD)
def get_weight(i, j):
return (H1[i] * H2[j]) % MOD
f = [0, 1, 2, -1, -1, 5, 9, -1, 8, 6]
add1 = []
query1 = []
add2 = []
query2 = []
for _ in range(N):
i, j, x = map(int, input().split())
i -= 1
j -= 1
add1.append(( i, j, (x * get_weight( i, j)) % MOD))
add2.append((H - i - 1, W - j - 1, (f[x] * get_weight(H - i - 1, W - j - 1)) % MOD))
Q = int(input())
for _ in range(Q):
l, d, r, u = map(int, input().split())
l -= 1
d -= 1
query1.append(( l, d, r, u))
query2.append((H - r, W - u, H - l, W - d))
ans1 = rectangle_sum(H, W, add1, query1)
ans2 = rectangle_sum(H, W, add2, query2)
for i in range(Q):
hash1, hash2 = ans1[i], ans2[i]
l, d, r, u = query1[i]
w1 = get_weight(l, d)
w2 = get_weight(H - r, W - u)
print("Yes" if (hash1 * w2) % MOD == (hash2 * w1) % MOD else "No")