結果
| 問題 | 
                            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")