hdu1541 Stars(树状数组+解释)


http://acm.hdu.edu.cn/showproblem.php?pid=1541

题意:有n个星星,输入时是以从下到上,从左到右的方式输入(x,y)的值。每个星星左下方有多少个星星就评多少等级,求0~n-1个等级分别有多少个星星。


思路:树状数组入门题,第二次做。首先上博客,这篇写的很好,看完就懂了。树状数组主要用的是二进制思想,相比于普通数组在更新和求和上从O(n)优化到了O(n-1)。

本题要求的是每个星星左下方有多少个星星,因为后遍历的肯定是上方,所以只需求出左边有多少个星星。这样我们把每个星星量化为一个,求左边有多少星星就是求和。这里每组最多15000个星星,还有多组,普通数组耗时过多。这样就用到了树状数组。树状数组那个大牛解释的很好了,不过为了巩固还是要写些注释。


这里我把每个lowbit换成了组的说法。


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>

using namespace std;

typedef long long ll;
const int N = 32001;

int tree[N];//从当前元素开始连续往左求lowbit(x)个数的和
int level[N];//保存等级

int lowbit(int x)
{
    return -x&x;
}

void add(int x)//更新
{
    while(x < N)//临界值32001,代表某一项改变临界区内相应组的值也要改变
    {
        tree[x]+=1;//涉及到的组加一,代表多一个等级(类似于打表)
        x+=lowbit(x);//去尾操作,变成下一个被涉及到的组
    }
}

int sum(int x)
{
    int rankk = 0;//星星的等级就相当于总和,每个星星左边有多少个星星,等级即为多少
    while(x > 0)//说明还有组可加
    {
        rankk+=tree[x];//总星数加上本星星左方每组有多少星星
        x-=lowbit(x);//用二分递减的规则使x变成下一组
    }
    return rankk;
}

int main()
{
  //  freopen("in.txt", "r", stdin);
    int n, x, y;
    while(~scanf("%d", &n))
    {
        memset(level, 0, sizeof(level));
        memset(tree, 0, sizeof(tree));
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d", &x, &y);
            level[sum(++x)]++;
            add(x);
        }
        for(int i = 0; i < n; i++)
            printf("%d\n", level[i]);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值