题目链接:传送门
思路:一开始一直想使用线段树保存染色信息。。然而发现这种做法非常困难,,然后看了题解,使用树状数组或者线段树维护在位置x的区间起点数量前缀和suma[n]和区间终点数量的前缀和sumb[n]即可 , 比如一段区间[a , b]的炸弹种类就是sumb[b] - suma[a-1]。
代码:(这里使用了线段树)
#include
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;
}