Official
A - 2x2 Erasing Editorial
by
A - 2x2 Erasing Editorial
by
sounansya
まず、 \((U_i,D_i,L_i,R_i)=(1,N,1,N)\) の場合を考えます。
マス \((r,c),(r,c+1),(r+1,c),(r+1,c+1)\) が全て白で塗られているような \((r,c)\) を辞書順に \((r_1,c_1),(r_2,c_2),\ldots,(r_K,c_K)\) とします。明らかに \(K\) 回が操作回数の上界として分かります。
そして、この上界は達成可能です。具体的には、 \(k=1,2,\ldots,K\) の順に \((r,c)=(r_k,c_k)\) を選びマス \((r_k,c_k)\) を黒く塗れば良いです。
この事実を踏まえると、各クエリでは与えられた二次元領域に含まれる全てが白で塗られているような \(2\times 2\) マスがいくつ含まれるかを計算すれば良いです。これは二次元累積和を用いることで \(O(N^2)\) 時間の前計算の元 \(O(1)\) 時間で計算できます。
以上を適切に実装することでこの問題に正答することができます。計算量は \(O(N^2 + Q)\) です。
n, q = map(int, input().split())
ss = [input() for _ in range(n)]
s = [[ss[i][j] == "." for j in range(n)] for i in range(n)]
a = [[0] * n for _ in range(n)]
for i in range(n - 1):
for j in range(n - 1):
a[i + 1][j + 1] = s[i][j] and s[i + 1][j] and s[i][j + 1] and s[i + 1][j + 1]
for i in range(n - 1):
for j in range(n):
a[i + 1][j] += a[i][j]
for i in range(n):
for j in range(n - 1):
a[i][j + 1] += a[i][j]
for _ in range(q):
u, d, l, r = map(int, input().split())
u, d, l, r = u - 1, d - 1, l - 1, r - 1
print(a[d][r] - a[d][l] - a[u][r] + a[u][l])
posted:
last update: