P1884 过度种植


传送门

思路

二维空间的离散化。可以选择统一离散或者分别离散。离散后用差分矩阵先覆盖点,再通过前缀和完成矩阵覆盖,最后计算矩阵面积。统一离散的分析:统一离散可以理解成分别离散形成的矩阵的再分割,它的计算过程相比分别离散会更加细分,把一个边分解成多段。

代码

#include 
#include
using namespace std;
int lsX[2022], lsY[2022], pX[2022], pY[2022], N, cnt;
bool map[2022][2022]; long long ans;
typedef long long ll;
int main(void)
{
    cin >> N;
    for (int i = 1; i <= N << 1; i++)
    {
        cin >> pX[i] >> pY[i];
        lsX[i] = pX[i];
        lsY[i] = pY[i];
    }
    lsX[0] = lsY[0] = INT32_MIN;
    sort(lsX + 1, lsX + N * 2 + 1);
    sort(lsY + 1, lsY + N * 2 + 1);
    int lenX = unique(lsX + 1, lsX + N * 2 + 1) - lsX - 1;
    int lenY = unique(lsY + 1, lsY + N * 2 + 1) - lsY - 1;
    for (int i = 1; i <= N; i++)
    {
        int lx = lower_bound(lsX + 1, lsX + lenX + 1, pX[2 * i - 1]) - lsX;
        int rx = lower_bound(lsX + 1, lsX + lenX + 1, pX[2 * i]) - lsX;
        int ly = lower_bound(lsY + 1, lsY + lenY + 1, pY[2 * i - 1]) - lsY;
        int ry = lower_bound(lsY + 1, lsY + lenY + 1, pY[2 * i]) - lsY;
        for (int i = min(lx, rx); i < max(lx, rx); i++)
            for (int j = min(ly, ry); j < max(ly, ry); j++)
                map[i][j] = true;
    }
    for (int i = 1; i < lenX; i++)
        for (int j = 1; j < lenY; j++)
            if (map[i][j])
                ans += ((ll)lsX[i + 1] - (ll)lsX[i]) * ((ll)lsY[j + 1] - (ll)lsY[j]);
    cout << ans << endl;
    return 0;
}