C. Rooks Defenders_BIT
作者:互联网
C. Rooks Defenders_BIT
题目大意
有n*n的棋盘,每次可以在任意位置放下或者拿走一个车。每个车可以攻击到他所在的一整行和一整列。每次查询给一个矩形区间,问区间内的每一个格子是否都能被攻击到。
思路和代码
首先x轴y轴分开考虑是好想的。
对两个轴维护BIT即可
要注意的是,BIT维护的是某一行或某一列是否能被攻击,我们还需要维护另外的数组表示某一行或某一列上有几辆小车。
当然还有一种做法,用线段树维护区间最小值也ok
struct Fenwick{
vct<ll> tr ;
int n ;
Fenwick(int m){
n = m ;
tr.resize(n + 1) ;
rep(i , 0 , n) tr[i] = 0 ;
}
void add(int x , int val){
while(x <= n){
tr[x] += val ;
x += (x & -x) ;
}
}
ll query(int x){
ll res = 0 ;
while(x){
res += tr[x] ;
x -= (x & -x) ;
}
return res ;
}
ll query(int l , int r){
return psum(r) - psum(l - 1) ;
}
};
int n , m , k ;
void solve(){
cin >> n >> m ;
Fenwick tx(n) , ty(n) ;
vct<ll> X(n + 1 , 0) ;
vct<ll> Y(n + 1 , 0) ;
while(m -- ){
int op , x , y , x1 , y1 ;
cin >> op >> x >> y ;
if(op == 1){
if(!X[x] ++ )tx.add(x , 1) ;
if(!Y[y] ++ )ty.add(y , 1) ;
}else if(op == 2){
if(! -- X[x])
tx.add(x , -1) ;
if(! -- Y[y])
ty.add(y , -1) ;
}else{
cin >> x1 >> y1 ;
ll numx = tx.query(x , x1) ;
ll numy = ty.query(y , y1) ;
if(numx == (x1 - x + 1) || numy == (y1 - y + 1)) cout << "YES\n" ;
else cout << "NO\n" ;
}
}
}//code_by_tyrii
标签:Rooks,ty,int,Defenders,add,y1,BIT,x1 来源: https://www.cnblogs.com/tyriis/p/16279815.html