题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6514
题目大意:给出p个矩阵,q次查询,问查询的矩阵中是否有点不存在于这p个矩阵中
题目思路:二维前缀和模板题,对于添加一个矩阵(x1,y1,x2,y2),需要a[x1][y1]+1(黄),a[x2+1][y]-1(红+黄),a[x1][y2+1]-1(深红+黄),由于右上角被删了两次,所以需要再a[x2+1][y2+1]+1。
然后现在矩阵处理下前缀和,来获得每个点被多少个矩阵覆盖过。计算的方法是a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1](根据刚才的方法理解),然后将>1的变成1,接着再处理前缀和,查询的时候就是a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1],如果等于(x2-x1+1)*(y2-y1+1),那么就说明每个点都被覆盖过,那么就是yes,否则就是no。由于数据范围是n*m<=1e7,所以需要把二维数组拍扁成一维,用i*m+j即可。
以下是代码:
#include
using namespace std;
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
const int MAXN = 1e7+5;
const int MOD = 998244353;
int n,m,q,x,y,xx,yy;
int a[MAXN];
int getid(int i,int j){
return i*m+j;
}
int main(){
while(~scanf("%d%d",&n,&m)){
memset(a,0,sizeof(a));
scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&x,&y,&xx,&yy);
a[getid(x,y)]++;
a[getid(xx+1,y)]--;
a[getid(x,yy+1)]--;
a[getid(xx+1,yy+1)]++;
}
rep(i,1,n){
rep(j,1,m){
a[getid(i,j)]+=a[getid(i-1,j)]+a[getid(i,j-1)]-a[getid(i-1,j-1)];
}
}
rep(i,1,n){
rep(j,1,m){
a[getid(i,j)]=(a[getid(i,j)]>0);
}
}
rep(i,1,n){
rep(j,1,m){
a[getid(i,j)]+=a[getid(i-1,j)]+a[getid(i,j-1)]-a[getid(i-1,j-1)];
}
}
scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&x,&y,&xx,&yy);
if(a[getid(xx,yy)]-a[getid(xx,y-1)]-a[getid(x-1,yy)]+a[getid(x-1,y-1)]==(xx-x+1)*(yy-y+1)){
puts("YES");
}
else{
puts("NO");
}
}
}
return 0;
}