公式
D - 照明パネルと額縁 / Lighting Panels and Picture Frames 解説
by
D - 照明パネルと額縁 / Lighting Panels and Picture Frames 解説
by
sounansya
行が \(A_i\) 以上 \(B_i\) 以下、列が \(C_i\) 以上 \(D_i\) 以下であるマスの状態を反転する操作は \(2\) 次元 imos 法を用いることで \(O(HW+N)\) 時間で計算することができます。
この計算したグリッドを元に、点灯したパネルの連結成分ごとに分解します。
1.指定された領域内にある、点灯しているマスの個数
上で計算したグリッドの状態を元に愚直に数え上げれば良いです。二次元累積和を用いることで \(O(1)\) 時間で計算できるようにすることもできます。
2.指定された領域内にある、点灯しているマスの個数
点灯したパネルの連結成分ごとに、その連結成分が全て長方形の領域に含まれるか判定し、完全に含まれる領域の個数を求めれば良いです。
from collections import deque
h, w, n = map(int, input().split())
g = [[False] * (w + 1) for _ in range(h + 1)]
for _ in range(n):
a, b, c, d = map(int, input().split())
a, c = a - 1, c - 1
g[a][c] ^= True
g[a][d] ^= True
g[b][c] ^= True
g[b][d] ^= True
for i in range(h):
for j in range(w + 1):
g[i + 1][j] ^= g[i][j]
for i in range(h + 1):
for j in range(w):
g[i][j + 1] ^= g[i][j]
visited = [[False] * (w) for _ in range(h)]
grids = []
for stx in range(h):
for sty in range(w):
if visited[stx][sty] or not g[stx][sty]:
continue
q = deque()
visited[stx][sty] = True
q.append((stx, sty))
xs = []
ys = []
while q:
x, y = q.popleft()
xs.append(x)
ys.append(y)
for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
xx, yy = x + dx, y + dy
if (
not (0 <= xx < h and 0 <= yy < w)
or visited[xx][yy]
or not g[xx][yy]
):
continue
visited[xx][yy] = True
q.append((xx, yy))
grids.append((min(xs), max(xs), min(ys), max(ys)))
m = int(input())
for _ in range(m):
p, q, r, s = map(int, input().split())
p, r = p - 1, r - 1
ans1 = 0
for x in range(p, q):
for y in range(r, s):
if g[x][y]:
ans1 += 1
ans2 = 0
for minx, maxx, miny, maxy in grids:
if p <= minx and maxx < q and r <= miny and maxy < s:
ans2 += 1
print(ans1, ans2)
投稿日時:
最終更新:
