poj 2352 Stars

树状数组经典题目

这里给一个大佬的树状数组:树状数组-博客园

题目描述:
Description

Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers want to know the distribution of the levels of the stars.

For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it’s formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.

You are to write a program that will count the amounts of the stars of each level on a given map.

天文学家经常研究星图,星图上的星星由平面上的点表示,每颗星星都有笛卡尔坐标。一颗星星的等级是指该星星左下方的星星的数量.
例如,查看上图所示的地图,5号星的等级为3(左下方有1、2、4号星),2号星和4号星的等级为1。在这张地图上有一颗0级的星星,两颗1级的星星,一颗2级的星星,和一颗3级的星星。 你需要写一个程序来计算给定星图上每个等级的星星数量

Input

The first line of the input file contains a number of stars N (1<=N<=15000). The following N lines describe coordinates of stars (two integers X and Y per line separated by a space, 0<=X,Y<=32000). There can be only one star at one point of the plane. Stars are listed in ascending order of Y coordinate. Stars with equal Y coordinates are listed in ascending order of X coordinate.

输入的第一行包括了星星的数量N (1<=N<=15000),下面N行描述了每颗星星的坐标(每一行由一个空格分隔两个整数X和Y组成, 0<=X,Y<=32000)。每一个点只会存在一颗星星。星星以Y坐标的升序排列。Y坐标相等的恒星按X坐标的升序排列。

Output

The output should contain N lines, one number per line. The first line contains amount of stars of the level 0, the second does amount of stars of the level 1 and so on, the last line contains amount of stars of the level N-1.

输出应该包括N行,每行一个数字。第一行为等级是0级的星星数量,第二行为等级是1级的星星数量,以此类推,最后一行为等级是N-1级的星星数量。

Sample Input

5
1 1
5 1
7 1
3 3
5 5
Sample Output

1
2
1
1
0

思路:
直接先写出树状数组的模板,树状数组具体原理我都还没搞懂,模板倒是记住了,很尴尬哈。本题有个需要注意的点,由于坐标的x,y可能为0,如果为0,我们调用函数是可能会存在一些问题,比如在add_num函数中,为0就会一直更新不了我们需要的a[i]的值,这里a就是我们的树状数组,因此我们+1。

代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
const int maxn=32005;
const int inf=0x3f3f3f3f;
int n,x,y;
int a[maxn],level[maxn];
int lowbit(int x) {
	return x&(-x);
}
void add_num(int i,int k){
	if(i==0) return;
	while(i<=32001){
		a[i]+=k;
		i+=lowbit(i);
	}
}
int getsum(int i){
	int ans=0;
	while(i>0){
		ans+=a[i];
		i-=lowbit(i);
	}
	return ans;
}
int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&x,&y);
		level[getsum(x+1)]++;
		add_num(x+1,1);
	}
	for(int i=0;i<n;i++) printf("%d\n",level[i]);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tran_sient

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值