けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

鉄則本 B09 - Papers (2Q, ★4)

二次元いもす法の練習問題

問題概要

二次元平面上に  N 枚の長方形の紙がある。 i 枚目の紙の左下の座標は  (A_{i}, B_{i}) であり、右上の座標は  (C_{i}, D_{i}) である。

紙に覆われている部分の面積を求めよ。

制約

  •  1 \le N \le 10^{5}
  •  0 \le A_{i} \lt C_{i} \le 1500
  •  0 \le B_{i} \lt D_{i} \le 1500

考えたこと

二次元いもす法の練習。

github.com

コード

#include <bits/stdc++.h>
using namespace std;
const int MAX = 1600;

int main() {
    int N;
    cin >> N;
    
    // いもす法の準備
    vector num(MAX + 1, vector(MAX + 1, 0));
    for (int i = 0; i < N; ++i) {
        int A, B, C, D;
        cin >> A >> B >> C >> D;
        ++num[A][B], --num[A][D], --num[C][B], ++num[C][D];
    }
    
    // いもす法の累積和
    for (int i = 0; i <= MAX; ++i) {
        for (int j = 0; j < MAX; ++j) num[i][j + 1] += num[i][j];
    }
    for (int j = 0; j <= MAX; ++j) {
        for (int i = 0; i < MAX; ++i) num[i + 1][j] += num[i][j];
    }
    
    // 集計
    int res = 0;
    for (int i = 0; i < MAX; ++i) {
        for (int j = 0; j < MAX; ++j) {
            if (num[i][j]) ++res;
        }
    }
    cout << res << endl;
}