题目大意:给你一个n*m的矩形,在这个矩形内告诉你p个矩形(左下角和右上角坐标),问你q个问题,每次也是给你一个矩形(左下角和右上角坐标),问你每个矩形是否可以被开始给的p个矩形完全覆盖。
思路:n*m范围是1e7,无法开二维数组,二维坐标可以转化为(n-1)*m+m,用一维数组来记录每个坐标的前缀和(即为这个点与0,0点组成矩形的面积),先通过二维差分,将前缀和记录一边。因为有覆盖的情况,所以将前缀和大于0的初始化为1,在来一遍前缀和,处理好之后就可以O(1)的时间算出每个矩形是否可以覆盖。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
int sum[maxn];
int d[maxn];
int n,m;
int fun(int x,int y)
{
int t=m*(y-1)+x;
if(t>=1&&t<=(n*m))
return t;
else
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
int p;
cin>>p;
for(int i=1; i<=p; i++)
{
int x1,y1,x2,y2;
cin>>y1>>x1>>y2>>x2;
d[fun(x1,y1)]+=1;
d[fun(x2+1,y2+1)]+=1;
d[fun(x1,y2+1)]-=1;
d[fun(x2+1,y1)]-=1;
}
for(int j=1; j<=n; j++)
for(int i=1; i<=m; i++)
{
sum[fun(i,j)]=sum[fun(i,j-1)]+sum[fun(i-1,j)]-sum[fun(i-1,j-1)]+d[fun(i,j)];
}
for(int i=1; i<=n*m; i++)
{
if(sum[i]!=0)
sum[i]=1;
}
// for(int j=n; j>=1; j--)
// {
// for(int i=1; i<=m; i++)
// {
// if(sum[fun(i,j)]!=0)
// printf("%d ",sum[fun(i,j)]);
// else
// printf("0 ");
// }
// printf("
");
// }
for(int j=1; j<=n; j++)
for(int i=1; i<=m; i++)
{
sum[fun(i,j)]+=sum[fun(i,j-1)]+sum[fun(i-1,j)]-sum[fun(i-1,j-1)];
}
int q;
cin>>q;
for(int i=1; i<=q; i++)
{
int x1,y1,x2,y2;
cin>>y1>>x1>>y2>>x2;
int ans=sum[fun(x2,y2)]-sum[fun(x2,y1-1)]-sum[fun(x1-1,y2)]+sum[fun(x1-1,y1-1)];
if(ans==((x2-x1+1)*(y2-y1+1)))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}