P2184 貪婪大陸(線段樹 or 樹狀數組)

題目鏈接:傳送門

思路:一開始一直想使用線段樹保存染色信息。。然而發現這種做法非常困難,,然後看了題解,使用樹狀數組或者線段樹維護在位置x的區間起點數量前綴和suma[n]和區間終點數量的前綴和sumb[n]即可 , 比如一段區間[a , b]的炸彈種類就是sumb[b] - suma[a-1]。

代碼:(這裏使用了線段樹)

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 5;

int sum[4 * maxn] , add[4 * maxn] , sum1[4 * maxn]; 
int x , y , p;



int query(int* obj , int o , int l , int r) {
	if(x <= l && r <= y) {
		return obj[o];
		//cout << "obj = " << obj[o] << "\n";	
	}
	else {
		int mid = (l + r) / 2;
		//push_down(o , l , r);
		int res = 0;
		if(x <= mid) res += query(obj , o << 1 , l , mid);
		if(y > mid)res += query(obj , o << 1 | 1, mid + 1, r);
		return res;
	}
}


void s_update(int* obj , int o , int l ,int r ,int d ) {
	if(l == r) {
		obj[o] += d;
	}
	else {
		int mid = (l + r) / 2;
		if(p <= mid)s_update(obj , o << 1 , l , mid , d);
		else s_update(obj , o << 1 | 1 , mid + 1 , r , d);
		obj[o] = obj[o << 1] + obj[o << 1 | 1];
	}
}

int main() {
	int n , m;
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	x = 1;
	while(m--) {
		int q , a , b;
		cin >> q >> a >> b;
		if(q == 1) {
			p = a;
			s_update(sum , 1 , 1 , n , 1);
			p = b;
			s_update(sum1 , 1 , 1 , n , 1);
		}
		else {
			int t1 , t2;
			y = b;
			t1 = query(sum , 1 , 1 , n);
			y = a - 1;
			t2 = query(sum1 , 1 , 1 , n);
			cout << t1 - t2 << endl;
		}
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章