链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556

题意:N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数[a,b]之间的气球染一次色,最后问每个气球染了多少种颜色。

分析:这是树状数组的第二种应用,区间成段更新,然后求某点的值。

update(x,num)表示x位置的值增加num,sum(x)表示求1到x的和。

更新[l,r]区间时,

先update(l,k),然后update(r+1,-k),就会导致sum(l)到sum(r)的值均增加了k,然后[1,l)和(r,max)这两个范围内的sum都不变,这样sum(x)就是x这个点当前的值了。

在纸上自己画一画,模拟一下就能明白了。

AC代码如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define N 100010
 4 int d[N],n;
 5 int lowbit(int x)
 6 {
 7     return x&(-x);
 8 }
 9 void update(int x,int num)
10 {
11     while(x<=n)
12     {
13         d[x]+=num;
14         x+=lowbit(x);
15     }
16 }
17 int GetSum(int x)
18 {
19     int s=0;
20     while(x>0)
21     {
22         s+=d[x];
23         x-=lowbit(x);
24     }
25     return s;
26 }  
27 int main()
28 {
29     int i,a,b;
30     while(scanf("%d",&n)&&n)
31     {
32         memset(d,0,sizeof(d));
33         for(i=0;i<n;i++)
34         {
35             scanf("%d%d",&a,&b);
36             update(a,1);
37             update(b+1,-1);
38         }
39         for(i=1;i<n;i++)
40             printf("%d ",GetSum(i));
41         printf("%d\n",GetSum(n));
42     }
43     return 0;
44 }
View Code

相关文章: