我看好像没有人用差分的思路,我就写一下给大佬们提供一个思路,但是本人语言能力有限,如果看不懂我在放什么屁可以在评论区讨论一下。本来看看能不能发题解的,但是不知道为啥这个题不让发题解了,就发在讨论区。这个题目的转换过程比较繁琐,而且要注意坐标点转化为矩阵这些细节,应用了二分查找,差分矩阵,离散化相关知识。我的思路是,用一个vecor存储所有矩阵的坐标,然后另外开两个vector数组分别存储所有的x坐标和y坐标,x、y坐标离散化之后调用所有的矩阵的坐标,把它们的坐标全部转化存储在一个一个小矩阵中,最后利用差分矩阵查看这些小矩阵哪些被标记了就计算它们的面积即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define N 3000
#define ll long long
int n;
typedef pair<int,int> PII;
vector<int> allx,ally;
vector<PII> rec[2];
int a[N][N],b[N][N];
int f(int x,vector<int> &y)//查找某个横坐标或者纵坐标离散化后的位置
{
int l=1,r=y.size()-1;
while(l<r)
{
int mid=(l+r)/2;
if(y[mid]<x)
l=mid+1;
else
r=mid;
}
return r;
}
void inser(int x1, int y1, int x2, int y2, int c)//差分
{
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
allx.push_back(0);
ally.push_back(0);//先插个0进去是因为本题为了把坐标转化为矩阵需要从1开始记录坐标
for(int i=0;i<n;i++)
{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
rec[0].push_back({x1,y1});
rec[1].push_back({x2,y2});
allx.push_back(x1);
allx.push_back(x2);
ally.push_back(y1);
ally.push_back(y2);
}
sort(allx.begin()+1,allx.end());
allx.erase(unique(allx.begin()+1,allx.end()),allx.end());
sort(ally.begin()+1,ally.end());
ally.erase(unique(ally.begin()+1,ally.end()),ally.end());//离散化的过程
for(int i=0;i<n;i++)
{
int x1=rec[0][i].first;
int y1=rec[0][i].second;
int x2=rec[1][i].first;
int y2=rec[1][i].second;
inser(f(x1,allx),f(y1,ally),f(x2,allx)-1,f(y2,ally)-1,1);//减一的操作就是把坐标转化为矩阵方格,各位可以模拟一下
}
for(int i=1;i<=allx.size();i++)
for(int j=1;j<=ally.size();j++)
a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j];
ll s=0;
for(int i=1;i<=allx.size();i++)
{
for(int j=1;j<=ally.size();j++)
{
if(a[i][j])//如果矩阵被标记过,说明这个矩阵所存储的坐标构成的实际矩阵被覆盖了,就加上这个矩阵的面积
{
int x1,y1,x2,y2;
x1 = allx[i];
y1 = ally[j];
x2 = allx[i + 1];
y2 = ally[j + 1];
s+=(ll)(x2-x1)*(y2-y1);
}
}
}
cout<<s<<endl;
return 0;
}