树状数组-校门外有很多树(nkoj1317)
题意分析
树状数组裸题
将问题转化为前缀和求解
本题需要巧妙???的转化来变成树状数组题
每次修改a,b]区间,查询[l,r]区间,那么只需算出有多少个[a,b]区间与[l,r]区间相交即可
即求符合
a≤r,l≤b
a
≤
r
,
l
≤
b
的区间个数,即求
|{a≤r}|−|{b<l}|
|
{
a
≤
r
}
|
−
|
{
b
<
l
}
|
利用树状数组记录前缀和即可
代码
//
// Created by rv on 2018/4/23.
//
#include <cstdio>
#include <cstring>
//const int N = 50000 + 5;
struct BIT {
int cnt;
int* s;
BIT(int n) {
cnt = n;
s = new int[n];
memset(s, 0, sizeof(int) * n);
}
void add(int pos, int delta) {
for (int i = pos; i <= cnt; i += i & -i) {
s[i] += delta;
}
}
int sum(int pos) {
int res = 0;
for (int i = pos; i >= 1; i -= i & -i) {
res += s[i];
}
return res;
}
};
int main() {
int n, m, k, l, r;
scanf("%d%d", &n, &m);
BIT cnta(n + 1);
BIT cntb(n + 1);
while (m--) {
scanf("%d%d%d", &k, &l, &r);
if (k == 1) {
cnta.add(l, 1);
cntb.add(r, 1);
} else if (k == 2) {
printf("%d\n", cnta.sum(r) - cntb.sum(l - 1));
} else {
printf("bad scanf\n");
}
}
return 0;
}