[POJ2352] Stars 夜空星辰 - 树状数组


题目描述

夜空中有N颗恒星(N≤100000),每颗恒星具有其坐标(x, y)(0≤x, y≤100000)。现在,天文学家要对这些恒星进行分类,分类的标准如下:对于任意一颗恒星S(x,y),如果存在k颗恒星,其x, y坐标均不大于S,则恒星S属于k类星。
如下图所示:第5颗恒星为3类星,这是由1、2、4三颗恒星均在其左下方而得出的,类似地第2、4两颗恒星为1类星,第3颗恒星为2类星。因此在这幅图中只有一颗0类星,共有二颗1类星,2类星和3类星各有一颗。
现给出N颗恒星的坐标,要求统计出0~N-1类星的个数。
这里写图片描述


输入格式

输入文件第一行包含一个整数N,表示恒星总数。
接下来的N行每行两个整数表示一颗恒星的坐标。不存在两颗星拥有相同的坐标。


输出格式

输出文件包含N行,每行包含一个整数,第i行表示第i-1类星的数量。


样例数据

样例输入

5
3 3
5 1
5 5
1 1
7 1

样例输出

1
2
1
1
0


数据范围

对于20%的数据,n<=1000;
对于100%的数据, n<=100000;


题目分析

要统计左下方的点数
二维不好统计,先按照x从小到大排序,因此就只用统计下方的点数了。
可以使用树状数组轻松解决。
树状数组维护y坐标,插入后查询比他小的求和即可


源代码

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
map<int,int>M,M2;
map<int,int>::iterator it;
int n,m,f[500005],ans[500005];
struct node {
    int x,y;
} a[500005];
const int Get_Int() {
    int n=0,bj=1;
    char x=getchar();
    while(x<'0'||x>'9'){
        if(x=='-')bj=-1;
        x=getchar();
    }
    while(x>='0'&&x<='9'){
        n=n*10+x-'0';
        x=getchar();
    }
    return n*bj;
}
int Lowbit(int x) {
    return x&-x;
}
void Add(int x,int d) {
    for(int i=x; i<=m; i+=Lowbit(i))f[i]+=d;
}
int Ask(int r) {
    int sum=0;
    for(int i=r; i>=1; i-=Lowbit(i))sum+=f[i];
    return sum;
}
bool cmp(node x,node y) {
    if(x.x==y.x)return x.y<=y.y;
    return x.x<y.x;
}
int main() {
    n=Get_Int();
    for(int i=1; i<=n; i++) {
        a[i].x=Get_Int()+1;
        a[i].y=Get_Int()+1;
        m=max(m,a[i].y);
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1; i<=n; i++) {
        ans[Ask(a[i].y)]++;
        Add(a[i].y,1);
    }
    for(int i=0; i<n; i++)printf("%d\n",ans[i]);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值