hdu 1556 Color the ball(树状数组)
链接: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 }
上面的方法是树状数组最基本的向上修改,向下统计的形式,其实还可以向上统计,向下修改。
树状数组中的每个节点都代表了一段线段区间,每次更新的时候,根据树状数组的特性可以把b以前包含的所有区间都找出来,然后把b以前的
区间全部加一次染色次数。然后,再把a以前的区间全部减一次染色次数,这样就修改了树状数组中的[a,b]的区间染色次数,查询每一个点总的染色次
数的时候,就可以直接向上统计每个父节点的值,就是包含这个点的所有区间被染色次数,这就是树状数组中向下查询,向上统计的典型应用
这样的话update()和sum()的代码就需要修改了,详见代码。
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>0) 12 { 13 d[x]+=num; 14 x-=lowbit(x); 15 } 16 } 17 int sum(int x) 18 { 19 int s=0; 20 while(x<=n) 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,-1); 37 update(b,1); 38 } 39 for(i=1;i<n;i++) 40 printf("%d ",sum(i)); 41 printf("%d\n",sum(n)); 42 } 43 return 0; 44 }
posted on 2013-08-16 21:38 jumpingfrog0 阅读(253) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步