题意:有两个操作,1是将车放入x,y,2是将x,y里的车删除,3是询问x1,y1,x2,y2里是不是所有的格子都被车攻击,车可以攻击他所在的一行和一列。
思路:想判断相应的行和列有没有被车攻击,我们就判断大于x1和x2的没有车的地方的行和列x和y,如果x小于x2说明有行没覆盖,如果y小于y1说明有列没有被覆盖,行和列相交肯定有一个格子没有覆盖,所以我们就按2这个来判断输出yes或no。被我们用两个set数组a,b分别来存没有被车攻击的行和列,初始时所有的都没有被攻击就把1-n的数全加入set里,然后用两个数组h,w分别来记录行和列上分别有几辆车,当进行操作1的时候我们放车,如果放的行和列上没有车的话,我们就对应的行和列在set里删除,h,w分别加。当进行2操作的时候,h,w分别减,再判断h,w是不是0,如果是的话说明没有车在相对应的行和列,将相对应的行和列加入set里。在进行操作3的时候,我们判断set数组a,b大于等于x1和y1的数,拿他们两个和x2,y2比较,如果有一个大说明有一行或一列全被车覆盖,输出yes,否则输出no。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
int n,q;
const int N=200010;
long long h[N],w[N];
set<int> a,b;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n+7;i++){
a.insert(i);
b.insert(i);
}
int t;
while(q--){
cin>>t;
int x,y,x1,y1,x2,y2;
if(t==1){
cin>>x>>y;
if(h[x]==0){
a.erase(x);
}
if(w[y]==0){
b.erase(y);
}
h[x]++;
w[y]++;
}else if(t==2){
cin>>x>>y;
h[x]--;
w[y]--;
if(h[x]==0){
a.insert(x);
}
if(w[y]==0){
b.insert(y);
}
}else{
cin>>x1>>y1>>x2>>y2;
x=*a.lower_bound(x1);
y=*b.lower_bound(y1);
if(x>x2||y>y2){
cout<<"Yes"<<'\n';
}else cout<<"No"<<'\n';
}
}
return 0;
}