D - 広告エリアの重複調査 / Investigation of Overlapping Advertisement Areas 解説 by admin
Claude 4.6 Opus (Thinking)Overview
On an \(N \times N\) bulletin board, we need to find the number of cells covered by both Takahashi’s advertisements (multiple rectangles) and Aoki’s advertisements (multiple rectangles). We use 2D imos method (2D prefix sum difference) to efficiently compute the coverage state of each cell.
Analysis
Naive Approach and Its Issues
The simplest method would be to consider all pairs of Takahashi’s and Aoki’s advertisements (up to \(A \times B = 10000\) pairs), compute the overlapping rectangle for each pair, and manage covered cells using a set. However, each rectangle can cover up to \(N^2 = 250000\) cells, making the overall computation potentially very large.
Key Insight
In this problem, it suffices to determine for each cell whether “it is covered by at least one of Takahashi’s advertisements” and whether “it is covered by at least one of Aoki’s advertisements.” Specifically, for each cell:
- Covered by one or more of Takahashi’s advertisements → flag ON
- Covered by one or more of Aoki’s advertisements → flag ON
- Count cells where both flags are ON
The operation of “adding a value to a rectangular region in bulk and then computing the cumulative value at each cell” can be efficiently performed using the 2D imos method.
Algorithm
How the 2D Imos Method Works
When we want to add \(+1\) to the rectangle from \((r_1, c_1)\) to \((r_2, c_2)\), we update the following 4 points in an \((N+2) \times (N+2)\) array:
- \(grid[r_1][c_1] += 1\)
- \(grid[r_1][c_2+1] -= 1\)
- \(grid[r_2+1][c_1] -= 1\)
- \(grid[r_2+1][c_2+1] += 1\)
After performing this operation for all rectangles, we take prefix sums in both the row and column directions, and the value at each cell \((r, c)\) becomes the number of rectangles covering that cell.
\[grid[r][c] += grid[r-1][c] + grid[r][c-1] - grid[r-1][c-1]\]
Procedure
- For Takahashi’s \(A\) advertisements, apply the 2D imos method additions to array
grid_a - For Aoki’s \(B\) advertisements, apply the 2D imos method additions to array
grid_b - Compute prefix sums for both arrays
- For each cell \((r, c)\), if \(grid\_a[r][c] > 0\) and \(grid\_b[r][c] > 0\), count it as an overlap
Concrete Example
For example, with \(N=5\), if Takahashi’s advertisement covers \((1,1)\) to \((3,3)\) and Aoki’s advertisement covers \((2,2)\) to \((4,4)\), then after computing prefix sums, the cells where \(grid\_a[r][c] > 0\) and \(grid\_b[r][c] > 0\) are \((2,2)\) to \((3,3)\), which is \(4\) cells.
Complexity
- Time complexity: \(O(N^2 + A + B)\)
- The difference updates for the imos method take \(O(A + B)\), and the prefix sum computation and counting take \(O(N^2)\)
- Space complexity: \(O(N^2)\)
- Two \((N+2) \times (N+2)\) arrays are used
Implementation Notes
By setting the array size to \((N+2) \times (N+2)\), we prevent out-of-bounds access even when \(r_2+1\) or \(c_2+1\) equals \(N+1\)
When computing prefix sums, don’t forget to subtract \(grid[r-1][c-1]\) (inclusion-exclusion principle)
The check \(grid\_a[r][c] > 0\) confirms “whether the cell is covered by at least one advertisement.” It doesn’t matter if multiple advertisements overlap — only whether the cell is covered or not is important
Using
sys.stdin.read()to read all input at once allows fast execution even in PythonSource Code
import sys
def main():
input_data = sys.stdin.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
A = int(input_data[idx]); idx += 1
B = int(input_data[idx]); idx += 1
# 2D imos for Takahashi
grid_a = [[0] * (N + 2) for _ in range(N + 2)]
for _ in range(A):
r1 = int(input_data[idx]); idx += 1
c1 = int(input_data[idx]); idx += 1
r2 = int(input_data[idx]); idx += 1
c2 = int(input_data[idx]); idx += 1
grid_a[r1][c1] += 1
grid_a[r1][c2 + 1] -= 1
grid_a[r2 + 1][c1] -= 1
grid_a[r2 + 1][c2 + 1] += 1
# 2D imos for Aoki
grid_b = [[0] * (N + 2) for _ in range(N + 2)]
for _ in range(B):
r1 = int(input_data[idx]); idx += 1
c1 = int(input_data[idx]); idx += 1
r2 = int(input_data[idx]); idx += 1
c2 = int(input_data[idx]); idx += 1
grid_b[r1][c1] += 1
grid_b[r1][c2 + 1] -= 1
grid_b[r2 + 1][c1] -= 1
grid_b[r2 + 1][c2 + 1] += 1
# Compute prefix sums and count overlaps
count = 0
for r in range(1, N + 1):
for c in range(1, N + 1):
grid_a[r][c] += grid_a[r - 1][c] + grid_a[r][c - 1] - grid_a[r - 1][c - 1]
grid_b[r][c] += grid_b[r - 1][c] + grid_b[r][c - 1] - grid_b[r - 1][c - 1]
if grid_a[r][c] > 0 and grid_b[r][c] > 0:
count += 1
print(count)
main()
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: