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;
}
posted @ 2020-03-03 21:09  优秀的渣渣禹  阅读(162)  评论(0编辑  收藏  举报