C. Rooks Defenders
题意:
三种操作:
1:给x,y添加一个R
2:给x,y删除一个R
3:查看从(x1,y1)到(x2,y2)这个矩形区间是否会被“攻击”完。
设定是一个R可以攻击横向和纵向所有的位置,
题解:
查看这个区间的横向或者纵向是否能被攻击完就行,关键的是如何实现它。
一个一个查询铁定会爆,此时采用set存横纵无攻击性的值,如果利用二分查找x1的下一个值大于x2或者y1的下一个值大于y2。则在此之间可以全部被攻击掉。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
const int maxn=2e5+7;
#define ll long long
const int mod=1e9+7;
set<int>he;//无攻击性
set<int>sh;//无攻击性
int h[maxn],s[maxn];
int main() {
int n,q;cin>>n>>q;
for(int i=1;i<=n+7;i++){//注意边界!!!
he.insert(i);
sh.insert(i);
}
int t;
while(q--){
cin>>t;
int xa,ya,xb,yb;
int x,y;
if(t==1){
sc("%d%d",&x,&y);
if(!h[x])he.erase(x);
if(!s[y])sh.erase(y);
h[x]++;
s[y]++;
}else if(t==2){
sc("%d%d",&x,&y);
h[x]--;
s[y]--;
if(!h[x])he.insert(x);
if(!s[y])sh.insert(y);
}else{
sc("%d%d",&xa,&ya);
sc("%d%d",&xb,&yb);
x=*he.lower_bound(xa);
y=*sh.lower_bound(ya);
if(x>xb||y>yb)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
return 0;
}