树状数组最基本的应用是单点更新,区间和查询,但本题略有不同,本题是区间更新,单点查询。我建立树状数组时用的是向上更新,向下求和,因此,只需在输入时将a到n这一区间都+1,再将b+1到n这一区间都-1即可完成数组的维护。最后输出每点对应的sum值即为被染色的次数。具体代码如下:
#include<bits/stdc++.h>
typedef long long ll;
const int maxn = 100010;
int n;
int a[maxn];
int lowbit(int k) {
return k & (-k);
}
void update1(int pos, int num) {//单点更新
while(pos <= n) {
a[pos] += num;//更新
pos += lowbit(pos);//向上更新受到影响的祖先结点
}
return;
}
int sum(int e) {//求一段区间的和
int sum = 0;
while(e > 0) {
sum += a[e];
e -= lowbit(e);
}
return sum;
}
int query(int a, int b) {//查询区间和
return sum(b) - sum(a-1);
}
int main() {
while(scanf("%d", &n) != EOF && n) {
int x, y;
memset(a, 0, sizeof(a));
for(int i = 1;i <= n;i++) {
scanf("%d %d", &x, &y);
update1(x, 1);
update1(y+1, -1);
}
for(int i = 1;i < n;i++)
printf("%d ", sum(i));
printf("%d\n", sum(n));
/*for(int i = 1;i <= n;i++)
printf("%d\n", sum(i));
for(int i = 1;i <= cas;i++) {
char ch;
scanf("\n%c", &ch);
int a, b, c;
if(ch == 'q') {
scanf("%d %d", &a, &b);
printf("%d\n", query(a, b));
}
else if(ch == 'c') {
scanf("%d %d %d", &a, &b, &c);
update1(a, c);
update1(b+1, -c);
}
}*/
}
return 0;
}