AcWing 1265. 数星星(升级 树状数组)

题目

思路:
因为直接进行二维前缀和,O(n^2) 别超时,所以用 树状数组为O(n*lg n).
因为输入时保证 一行一行输入,所以只要计算x坐标的增加。图中的A[x] 表示坐标为x 时,当前输入过有多少星星。此数组用 树状数组 表示。
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=32010;
int tr[N] ,le[15010];


//树状数组3个常规操作 
int lowbit(int x)
{
	return x & -x;
}

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

void add(int x)
{
	for(int i=x;i<N;i+=lowbit(i)) tr[i]++; //此处需要注意小于 N 。因为你并不知道后面的 x 有多大,所以开到最大 
	//1264 题直接小于 n 就可以,因为输入时提前给出数组的长度
}

int main()
{
	int n;
	cin>>n;
	
	for(int i=0;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x++;//因为树状数组下标从 1 开始,所以 ++  
		le[sum(x)]++;//横坐标加了一个 星星,所以星星的级数 ++ 
		add(x);// 加过级数后进行 树状数组 的++,因为刚加的星星不能算到里面 
	}
	
	for(int i=0;i<n;i++) printf("%d\n",le[i]);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值