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

来源:互联网 发布:结婚证合成软件 编辑:程序博客网 时间:2024/04/30 11:50

题目描述

夜空中有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
原创粉丝点击