D - 広告エリアの重複調査 / Investigation of Overlapping Advertisement Areas 解説 by admin
gemini-3-flash-thinkingOverview
Given an \(N \times N\) bulletin board, Takahashi pastes \(A\) rectangular advertisements and Aoki pastes \(B\) rectangular advertisements. The problem asks us to find the total number of cells that are covered by both “at least one of Takahashi’s advertisements” and “at least one of Aoki’s advertisements.”
Analysis
The bulletin board size \(N\) is at most 500, so the total number of cells is \(N^2 = 250,000\). With this size, it is feasible to store information about “whose advertisement covers each cell” in memory and count directly.
Naive Approach
For each advertisement, one could loop over the specified rectangular range from \((r_1, c_1)\) to \((r_2, c_2)\) and mark those cells as “covered.” However, with this approach, if a single advertisement covers the entire board, it takes \(O(N^2)\) computation per advertisement. Since the number of advertisements is \(A+B \le 200\), the total becomes \(O((A+B)N^2) \approx 5 \times 10^7\), which may be too slow for languages like Python given the time limit.
Efficient Solution: 2D Imos Method
To add values to rectangular regions more efficiently, we use the 2D imos method (2D difference array). With the 2D imos method, adding to a single rectangular region can be done in \(O(1)\). After processing all advertisements, by computing the 2D prefix sum, we can determine how many advertisements cover each cell in \(O(N^2)\).
Algorithm
- Prepare the grids:
Prepare a grid
grid_Tfor Takahashi and a gridgrid_Afor Aoki. The size is \((N+2) \times (N+2)\) to prevent out-of-bounds access. - Plot the advertisements (imos method):
For each advertisement \((r_1, c_1, r_2, c_2)\), perform additions and subtractions at the following 4 points:
grid[r1][c1] += 1grid[r1][c2+1] -= 1grid[r2+1][c1] -= 1grid[r2+1][c2+1] += 1
- Compute the prefix sums: For each grid, take the prefix sum in the row direction, then in the column direction, to recover how many advertisements cover each cell \((r, c)\).
- Count the overlapping cells:
Scan all cells \((r, c)\) (\(1 \le r, c \le N\)) and count the number of cells where
grid_T[r][c] > 0andgrid_A[r][c] > 0.
Complexity
- Time complexity: \(O(N^2 + A + B)\)
- Plotting the advertisements takes \(O(A+B)\), and computing the prefix sums and tallying takes \(O(N^2)\). When \(N=500\), \(N^2 = 250,000\), which is sufficiently fast.
- Space complexity: \(O(N^2)\)
- Memory is needed to store a few \(N \times N\) grids.
Implementation Notes
Handling 1-based indexing: The coordinates in the problem start from 1. By setting the array size to \(N+2\), we can use the coordinates directly as indices while elegantly preventing out-of-bounds access for
r2+1andc2+1used in the imos method.Prefix sum optimization: The process of taking the prefix sum row by row and then column by column can be written as a double loop. In the provided code, additions are performed row by row with consideration for memory efficiency and speed.
Source Code
import sys
def solve():
# Set recursion limit just in case
sys.setrecursionlimit(2000)
# Fast I/O: read all input at once and split by whitespace
try:
input_data = sys.stdin.read().split()
except EOFError:
return
if not input_data:
return
# Board size N, number of Takahashi's ads A, number of Aoki's ads B
N = int(input_data[0])
A = int(input_data[1])
B = int(input_data[2])
# grid_T and grid_A will store the 2D difference arrays for Takahashi and Aoki.
# We use (N + 2) x (N + 2) to safely handle 1-based indexing and (r2+1, c2+1) boundaries.
grid_T = [[0] * (N + 2) for _ in range(N + 2)]
grid_A = [[0] * (N + 2) for _ in range(N + 2)]
idx = 3
# Process Takahashi's A ads and update the difference array
for _ in range(A):
if idx + 3 >= len(input_data):
break
r1, c1, r2, c2 = map(int, input_data[idx:idx+4])
idx += 4
# Standard 2D Imos/difference array update for a rectangle
grid_T[r1][c1] += 1
grid_T[r1][c2+1] -= 1
grid_T[r2+1][c1] -= 1
grid_T[r2+1][c2+1] += 1
# Process Aoki's B ads and update the difference array
for _ in range(B):
if idx + 3 >= len(input_data):
break
r1, c1, r2, c2 = map(int, input_data[idx:idx+4])
idx += 4
# Standard 2D Imos/difference array update for a rectangle
grid_A[r1][c1] += 1
grid_A[r1][c2+1] -= 1
grid_A[r2+1][c1] -= 1
grid_A[r2+1][c2+1] += 1
# Compute 2D prefix sums for grid_T to determine which cells are covered
# Step 1: Row-wise prefix sum
for r in range(1, N + 1):
row = grid_T[r]
for c in range(1, N + 1):
row[c] += row[c-1]
# Step 2: Column-wise prefix sum
for r in range(1, N + 1):
curr_row = grid_T[r]
prev_row = grid_T[r-1]
for c in range(1, N + 1):
curr_row[c] += prev_row[c]
# Compute 2D prefix sums for grid_A and simultaneously count overlapping cells
# Step 1: Row-wise prefix sum for grid_A
for r in range(1, N + 1):
row = grid_A[r]
for c in range(1, N + 1):
row[c] += row[c-1]
ans = 0
# Step 2: Column-wise prefix sum for grid_A and check overlap with Takahashi's coverage
for r in range(1, N + 1):
curr_row_A = grid_A[r]
prev_row_A = grid_A[r-1]
row_T = grid_T[r]
for c in range(1, N + 1):
curr_row_A[c] += prev_row_A[c]
# If the cell (r, c) is covered by at least one ad from both Takahashi and Aoki
if curr_row_A[c] > 0 and row_T[c] > 0:
ans += 1
# Print the final count of overlapping squares
sys.stdout.write(str(ans) + '\n')
if __name__ == '__main__':
solve()
This editorial was generated by gemini-3-flash-thinking.
投稿日時:
最終更新: