Color the ball

Color the ball
Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
 

Input

每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。 
当N = 0,输入结束。
 

Output

每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。
 

Sample Input

     
     
3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
 

Sample Output

     
     
1 1 1 3 2 1
 
思路:
        这题就是将末端的数加一后的不断+lowbit()后面的数减一,为什么?举个栗子:假如在2 4之间,那2与4都要更新1,
一直更新到最大的气球数为止。而2就不断更1,4就加一为5后不断减一,这样就形成了一个【2,4】的区间了。再加5 6进来。
那5要更新1,六要更新1,之后就一增一降就抵消了。那5从2,4就为-1了,再加1就变了0.所以它再加点4那个1值就为一了。
(凡是从奇数变了偶数,都只会加偶数)
树状数组:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int cnt[100010],n;
int lowbit(int x)
{
	return x&(-x);
}
void update(int i, int j)
{
	while (i<=n)
	{
		cnt[i]+=j;
		i+=lowbit(i);
	}
}
int sum(int i)
{
	int t=0;
	while (i>0)
	{
		t+=cnt[i];
		i-=lowbit(i);
	}
	return t;
}
int main()
{
	int m,i,k,j;
	while(~scanf("%d",&n)&&n)
	{
		memset(cnt,0,sizeof(cnt));
		j=n;
		while (j--)
		{
			scanf("%d %d",&m,&k);
			update(m,1);
			//线段树是只要更新2的n次方的数就行了,所以要控制他的范围
			update(k+1,-1);
		}
		printf("%d",sum(1));  
		for(i=2;i<=n;i++)  
			printf(" %d",sum(i));  
		printf("\n");  
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值