HDU 1541 Stars

题意:给出N颗星星  每颗星星的位置坐标是Xi,Yi  给出顺序为以坐标Y为第一关键字 升序给出   当Y相同的时候  以X为第二关键字  升序给出   一颗星星的等级 = 它左下的星星个数总和    现让你求出每个等级(0~N-1)的星星一共有多少颗   

解题思路:因为星星是以Y为第一关键字以升序的方式给出    所以后给出的星星肯定是在前面星星的上面(或同行左边)   所以只要考虑X的坐标就可以了    如果当前X的坐标大于等于之前已经给出的星星的X的坐标   那么就满足条件   这个星星的level就加一    之后就变成一个求和的过程     这样的话就可以用线段树或树状数组去做了   具体解释看代码



#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<list>
#include<stack>
#include<vector>
#include<math.h>
#include<stdlib.h>
#include<time.h>u
using namespace std;
#define ll __int64
#define mem(a) memset(a,0,sizeof(a))
#define CLR(a, b) memset(a, b, sizeof(a))
#define INF 0x3f3f3f

const int maxn = 15005;	  //星星个数的最大值
const int size = 32005;   //坐标的最大值
int c[size],n;			//C数组的下标为就表示X 其值就等于坐标比X小的星星个数有多少个
int ans[maxn];			//下标表示等级 用来记录这个等级的星星个数有多少个


//树状数组
int lowbit(int x){
	return x&(-x);
}

void change(int pos,int x){
	while(pos <= size){
		c[pos] += x;
		pos += lowbit(pos);
	}
}

int query(int pos){
	int sum = 0;
	while(pos >= 1){
		sum += c[pos];
		pos -= lowbit(pos);
	}
	return sum;
}

int main(){
	while(scanf("%d",&n) != EOF){
		mem(ans);
		mem(c);
		for(int i = 1 ;i <= n;i++){
			int x,y;
			scanf("%d%d",&x,&y);    //这边就无需考虑Y了 直接可以用X去判断
			ans[query(x+1)]++;		// 星星个数求和即为等级

			change(x+1,1);			//只要坐标比X大的星星等级都加上1
		}
		for(int i = 0;i < n;i++)  printf("%d\n",ans[i]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值