其他分享
首页 > 其他分享> > C. Rooks Defenders_BIT

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