数星星 树状数组

在这里插入图片描述在这里插入图片描述

输入样例
5
1 1
5 1
7 1
3 3
5 5
输出样例
1
2
1
1
0
这里使用的是树状数组算法计算,核心函数有三个,因为输入是按照y相同x升序,其他的y升序方法输入,我们可以边输入边处理,(如果不按照这个方法输入,那么可以自己排序这样处理)
因为在处理到这个坐标时比该坐标纵坐标y更大的星星还没有录入系统,那么我们并且比该坐标横坐标x更小的星星已经录入完毕,所以当这个星星录入时,它的等级其实就已经确定了,而且我们可以把已经录入的所有星星的按照x坐标树状数组的方式存储在各个数组,在这个星星录入时再按照树状数组求前缀和的逻辑进行求和,并且不必担心这时我们要求和的数组里有星星不符合题目要求,因为比它纵坐标大的还没计算进去呢,所以肯定都是纵坐标比它小的,我们只需要算存储x下标星星个数数组[0-x]的和即可。
这里x二进制末尾有k个0,lowbit函数返回的是2k,tr[i]数组是指已经录入的星星的横标在 i-lowbit(i)—i 的星星个数之和,level[i]个数是等级为i的星星个数。
最后注意星星的横纵坐标范围,和最后输出时是输出是N行。
使用树状数组x下标不能为0,否则lowbit返回值没有意义。
#include<bits/stdc++.h>//树状数组题x不能为0! 
using namespace std;
const int N=35000+5;
int tr[N],level[N];
int n;

int lowbit(int x){
	return x&(-x);//因此x不能为0 
}

void add(int x){
	for(int i=x;i<N;i+=lowbit(i))	tr[i]++;
}

int sum(int x){
	int sum_s=0;
	for(int i=x;i>0;i-=lowbit(i)){
		sum_s+=tr[i];
	}
	return sum_s;
}

int main()
{
	scanf("%d",&n);
	int x,y;
	
	for(int i=0;i<n;i++){//n表示一共由n组数 
		scanf("%d%d",&x,&y);
		x++;
		level[sum(x)]++;//sum(x)是在该点左下方星星总数,level表示该级别星星个数
		add(x); 
	}
	for(int i=0;i<n;i++){
		printf("%d\n",level[i]);
	}
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值