hdu6514 Monitor
解题思路
这是一个二维前缀和就可以做的题目
差分维护区间,然后前缀和求出每个点覆盖的次数,将覆盖次数大于1的点的次数改为1后,求一次前缀和(此时变为前缀的覆盖点数)
对于每个询问,只需求询问区间的覆盖点数,比较覆盖点数是否等于这个区间的总点数,若等于则完全覆盖。
#define B cout << "BreakPoint" << endl;
#define O(x) cout << #x << " " << x << endl;
#define O_(x) cout << #x << " " << x << " ";
#define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#define LL long long
const int inf = 1e9 + 9;
using namespace std;
inline int read() {
int s = 0,w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-')
w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
s = s * 10 + ch - '0';
ch = getchar();
}
return s * w;
}
const int N = 1e7 + 5;
int a[N],n,m,q,s;
void add(int x,int y,int z){
if(x < 1 || y < 1 || x > n || y > m) return;
a[(x - 1) * m + y] += z;
}
int query(int x,int y){
if(!x || !y) return 0;
return a[(x - 1) * m + y];
}
void init(){
memset(a,0,sizeof(a));
q = read();
while(q--){
int x1 = read(),y1 = read(),x2 = read(),y2 = read();
add(x1,y1,1),add(x2 + 1,y2 + 1,1);
add(x1,y2 + 1,-1),add(x2 + 1,y1,-1);
}
s = n * m;
for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) a[(i - 1) * m + j] += query(i - 1,j) + query(i,j - 1) - query(i - 1,j - 1);
for(int i = 1;i <= s;i++) if(a[i]) a[i] = 1;
}
void solve(){
for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) a[(i-1) * m + j] += query(i - 1,j) + query(i,j - 1) - query(i - 1,j - 1);
q = read();
while(q--){
int x1 = read(),y1 = read(),x2 = read(),y2 = read();
if(query(x2,y2) - query(x1 - 1,y2) - query(x2,y1 - 1) + query(x1 - 1,y1 - 1) == (y2 - y1 + 1) * (x2 - x1 + 1)) puts("YES");
else puts("NO");
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF) init(),solve();
return 0;
}