第一次看这题的时候确实不知道怎么下手,看了别人的题解后才恍然大悟。地址在这里http://www.cnblogs.com/Xiper/p/4470218.html
就是先将车和矩形(右边)放在一起对x坐标排序,然后从小到大处理。维护一棵线段树,对于车,更新线段树的最小值。对于矩形,查询矩形的竖边区间的线段树的最小值,只要最小值大于该矩形的左边的x坐标,就说明该矩形被保护。然后对y坐标也类似处理。
然后写代码的时候逻辑一定要清楚,不然容易出各种各样的错。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAX 100010
#define lson root<<1,front,mid
#define rson root<<1|1,mid+1,rear
using namespace std;
int n,m,k,q;
struct node{
int kind;// 0 for car, 1 for square
int x,y,x0,y0;
int protect;//square
int index;//square
}s[MAX<<2];
int tree[MAX<<2];
bool sort1(node a,node b){
if(a.x<b.x)
return true;
else if(a.x==b.x){
if(a.kind==0)
return true;
else
return false;
}
return false;
}
bool sort2(node a,node b){
if(a.y<b.y)
return true;
else if(a.y==b.y){
if(a.kind==0)
return true;
else
return false;
}
return false;
}
bool sort3(node a,node b){
return a.index<b.index;
}
void pushup(int root){
tree[root]=min(tree[root<<1],tree[root<<1|1]);
}
void build(int root,int front,int rear){
if(front==rear){
tree[root]=0;
return;
}
int mid=(front+rear)>>1;
build(lson);
build(rson);
pushup(root);
}
void update(int root,int front,int rear,int pos,int value){//ÿ´Î¸üÐÂÒ»¶¨»áÈ¡´úÔÀ´µÄ¾ÉÖµ
if(front==rear){
tree[root]=value;
return;
}
int mid=(front+rear)>>1;
if(mid>=pos)
update(lson,pos,value);
if(mid<pos)
update(rson,pos,value);
pushup(root);
}
int query(int root,int front,int rear,int l,int r){
if(front>=l&&rear<=r){
return tree[root];
}
int mid=(front+rear)>>1;
int ret=m+n;
if(mid>=l)
ret=min(ret,query(lson,l,r));
if(mid+1<=r)
ret=min(ret,query(rson,l,r));
return ret;
}
int main(){
while(~scanf("%d %d %d %d",&n,&m,&k,&q)){
int a,b,c,d;
for(int i=0;i<k;i++){
scanf("%d %d",&a,&b);
s[i].kind=0;
s[i].x=a,s[i].y=b;
s[i].index=q;
}
for(int i=k;i<k+q;i++){
scanf("%d %d %d %d",&a,&b,&c,&d);
s[i].kind=1;
s[i].x=c,s[i].y=d,s[i].x0=a,s[i].y0=b;
s[i].protect=0,s[i].index=i-k;
}
//x
sort(s,s+k+q,sort1);
build(1,1,m);
for(int i=0;i<k+q;i++){
if(s[i].kind==0){
update(1,1,m,s[i].y,s[i].x);
}
else{
int ret=query(1,1,m,s[i].y0,s[i].y);
if(ret>=s[i].x0)//
s[i].protect=1;
}
}
//y
sort(s,s+k+q,sort2);
build(1,1,n);
for(int i=0;i<k+q;i++){
if(s[i].kind==0){
update(1,1,n,s[i].x,s[i].y);
}
else{
if(s[i].protect==1)
continue;
int ret=query(1,1,n,s[i].x0,s[i].x);
if(ret>=s[i].y0)//
s[i].protect=1;
}
}
sort(s,s+k+q,sort3);
for(int i=0;i<q;i++){
if(s[i].protect==1)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}