链接: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 }