链接
点击跳转
题解
其实就是查询一个子矩形中是否每一行都有一个車,或者每列都有一个車,这两个条件满足其一就是
y
e
s
yes
yes
现在考虑怎么查询是否每行都有一个車
那么其实就是把
[
x
1
,
x
2
]
[x_1,x_2]
[x1,x2]这几行的車拿出来,然后看看纵坐标在
y
1
,
y
2
y_1,y_2
y1,y2的那些,是不是在
[
x
1
,
x
2
]
[x_1,x_2]
[x1,x2]每行都出现了,我把所有的車按照纵坐标排序,从左往右依次加入,当我把
y
2
y_2
y2这一排的都加入完了之后,我只需要看下
[
x
1
,
x
2
]
[x_1,x_2]
[x1,x2]这些行中每行最后一个出现的車纵坐标是否大于等于
y
1
y_1
y1就行了
代码
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 200010
#define maxe 100010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std
;
using namespace __gnu_pbds
;
typedef long long ll
;
typedef pair
<int,int> pii
;
typedef pair
<ll
,ll
> pll
;
ll
read(ll x
=0)
{
ll c
, f(1);
for(c
=getchar();!isdigit(c
);c
=getchar())if(c
=='-')f
=-f
;
for(;isdigit(c
);c
=getchar())x
=x
*10+c
-0x30;
return f
*x
;
}
struct SegmentTree
{
#define inf 0x3f3f3f3f
int mn
[maxn
<<2], mx
[maxn
<<2], sum
[maxn
<<2], add
[maxn
<<2], set
[maxn
<<2], L
[maxn
<<2], R
[maxn
<<2];
void maketag_set(int o
, int v
)
{
add
[o
]=0;
set
[o
]=v
;
mx
[o
]=mn
[o
]=v
;
sum
[o
]=(R
[o
]-L
[o
]+1)*v
;
}
void maketag_add(int o
, int v
)
{
add
[o
]+=v
;
mx
[o
]+=v
, mn
[o
]+=v
;
sum
[o
]+=(R
[o
]-L
[o
]+1)*v
;
}
void pushdown(int o
)
{
if(L
[o
]==R
[o
])return;
if(~set
[o
])
{
maketag_set(o
<<1,set
[o
]);
maketag_set(o
<<1|1,set
[o
]);
set
[o
]=-1;
}
if(add
[o
])
{
maketag_add(o
<<1,add
[o
]);
maketag_add(o
<<1|1,add
[o
]);
add
[o
]=0;
}
}
void pushup(int o
)
{
mx
[o
]=max(mx
[o
<<1],mx
[o
<<1|1]);
mn
[o
]=min(mn
[o
<<1],mn
[o
<<1|1]);
sum
[o
]=sum
[o
<<1]+sum
[o
<<1|1];
}
void build(int o
, int l
, int r
)
{
int mid(l
+r
>>1);
L
[o
]=l
, R
[o
]=r
;
add
[o
]=0;
set
[o
]=-1;
mx
[o
]=mn
[o
]=sum
[o
]=0;
if(l
==r
)return;
build(o
<<1,l
,mid
);
build(o
<<1|1,mid
+1,r
);
pushup(o
);
}
void segset(int o
, int l
, int r
, int v
)
{
int mid(L
[o
]+R
[o
]>>1);
if(l
<=L
[o
] and r
>=R
[o
]){maketag_set(o
,v
);return;}
pushdown(o
);
if(l
<=mid
)segset(o
<<1,l
,r
,v
);
if(r
>mid
)segset(o
<<1|1,l
,r
,v
);
pushup(o
);
}
void segadd(int o
, int l
, int r
, int v
)
{
int mid(L
[o
]+R
[o
]>>1);
if(l
<=L
[o
] and r
>=R
[o
]){maketag_add(o
,v
);return;}
pushdown(o
);
if(l
<=mid
)segadd(o
<<1,l
,r
,v
);
if(r
>mid
)segadd(o
<<1|1,l
,r
,v
);
pushup(o
);
}
int segsum(int o
, int l
, int r
)
{
pushdown(o
);
int mid(L
[o
]+R
[o
]>>1), ans(0);
if(l
<=L
[o
] and r
>=R
[o
])return sum
[o
];
if(l
<=mid
)ans
+=segsum(o
<<1,l
,r
);
if(r
>mid
)ans
+=segsum(o
<<1|1,l
,r
);
return ans
;
}
int segmin(int o
, int l
, int r
)
{
int mid(L
[o
]+R
[o
]>>1), ans(inf
);
if(l
<=L
[o
] and r
>=R
[o
])return mn
[o
];
pushdown(o
);
if(l
<=mid
)ans
=min(ans
,segmin(o
<<1,l
,r
));
if(r
>mid
)ans
=min(ans
,segmin(o
<<1|1,l
,r
));
return ans
;
}
int segmax(int o
, int l
, int r
)
{
int mid(L
[o
]+R
[o
]>>1), ans(-inf
);
if(l
<=L
[o
] and r
>=R
[o
])return mx
[o
];
pushdown(o
);
if(l
<=mid
)ans
=max(ans
,segmax(o
<<1,l
,r
));
if(r
>mid
)ans
=max(ans
,segmax(o
<<1|1,l
,r
));
return ans
;
}
#undef inf
}segtree
;
pll rook
[maxn
];
ll ans
[maxn
], id
[maxn
];
pair
<pll
,pll
> r
[maxn
];
int main()
{
ll i
, j
, n
, m
, k
, q
, p
;
n
=read(), m
=read(), k
=read(), q
=read();
rep(i
,k
)
rook
[i
].fi
=read(), rook
[i
].se
=read();
rep(i
,q
)
r
[i
].fi
.fi
=read(), r
[i
].fi
.se
=read(), r
[i
].se
.fi
=read(), r
[i
].se
.se
=read(), id
[i
]=i
;
sort(rook
+1,rook
+k
+1,[](pll p1
, pll p2
){return p1
.se
<p2
.se
;});
sort(id
+1,id
+q
+1,[](ll a
, ll b
){return r
[a
].se
.se
<r
[b
].se
.se
;});
segtree
.build(1,1,n
);
for(j
=1,p
=1;j
<=q
;j
++)
{
while(p
<=k
and rook
[p
].se
<=r
[id
[j
]].se
.se
)
segtree
.segset(1,rook
[p
].fi
,rook
[p
].fi
,rook
[p
].se
), p
++;
ans
[id
[j
]]+=(segtree
.segmin(1,r
[id
[j
]].fi
.fi
,r
[id
[j
]].se
.fi
)>=r
[id
[j
]].fi
.se
);
}
sort(rook
+1,rook
+k
+1,[](pll p1
, pll p2
){return p1
.fi
<p2
.fi
;});
sort(id
+1,id
+q
+1,[](ll a
, ll b
){return r
[a
].se
.fi
<r
[b
].se
.fi
;});
segtree
.build(1,1,m
);
for(j
=1,p
=1;j
<=q
;j
++)
{
while(p
<=k
and rook
[p
].fi
<=r
[id
[j
]].se
.fi
)
segtree
.segset(1,rook
[p
].se
,rook
[p
].se
,rook
[p
].fi
), p
++;
ans
[id
[j
]]+=(segtree
.segmin(1,r
[id
[j
]].fi
.se
,r
[id
[j
]].se
.se
)>=r
[id
[j
]].fi
.fi
);
}
rep(i
,q
)if(ans
[i
])printf("YES\n");
else printf("NO\n");
return 0;
}