題目鏈接:傳送門
思路:一開始一直想使用線段樹保存染色信息。。然而發現這種做法非常困難,,然後看了題解,使用樹狀數組或者線段樹維護在位置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;
}