結果
問題 |
No.3207 Digital Font
|
ユーザー |
|
提出日時 | 2025-07-15 19:21:53 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 2,989 ms / 3,000 ms |
コード長 | 4,366 bytes |
コンパイル時間 | 166 ms |
コンパイル使用メモリ | 82,360 KB |
実行使用メモリ | 167,044 KB |
最終ジャッジ日時 | 2025-07-16 21:18:22 |
合計ジャッジ時間 | 73,160 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
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 = (1 << 61) - 1 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: l, d, r, u = query[i % Q] 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[i] -= seg.prod(d, u) ans[i] %= MOD else: ans[i % Q] += seg.prod(d, u) ans[i % Q] %= 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")