数星星

题目描述

天空上有很多的星星,非常的漂亮。每颗星星都有自己独特的坐标。聪聪给每颗星星一个等级,表示在这颗星星左下边(包括正左和正下)的星星个数。

给定星星的位置输出各级星星的数目。
给定N个点,定义每个点的等级是在该点左下方(含相等)的点的数目,试统计每个等级有多少个点。(1≤N≤15 000,x≤32 000,0≤ y≤32 000)

输入

第一行一个整数N(1≤N≤15 000),表示星星的数目。
接下来N行给出每颗星星的坐标,两个整数x,y.
不会有星星重叠。星星按Y坐标增序给出,Y坐标相同的按X坐标增序给出。

输出

N行,每行一个整数,分别是0级,1级,2级....N-1级的星星的数目。

样例输入

5
1 1
5 1
7 1
3 3
5 5

样例输出

1
2
1
1
0

Solution

定义一颗星星的等级就是它左下方星星的数量(包括正左和正下)

那么怎么求呢?我们发现题目中点的坐标的输入顺序是有故事的,什么鬼,是很好操作的,因为当一个点的坐标被给出时,它的等级就是出现在它之前的点中满足条件的点的数量,不会出现后面的点还有可能对这个点的等级有贡献这种情况

那么就好办了

一个点满足条件的意思就是它的横纵坐标都满足条件,所以就分别询问前缀和嘛,看之前有多个点,取个最小值就可以了(两个条件都满足),单点询问前缀和,那应该可以想到树状数组了吧

用两个树状数组,分别维护一个点的两个坐标

注意1:要先查询再插入,因为题目中说可能有坐标相同的点
注意2:要离散,不然死活T一个点,不会离散的看这里,后来发现要离散是因为数据里面有0,而lowbit(0)是等于0的,所以死循环,而离散就会解决这个问题,其实把所有坐标都+1就可以了

Code

#include<bits/stdc++.h>
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)

using namespace std;

const int N=2e4+10,Q=32010;

void in(int &ans)
{
    ans=0;int f=1; char i=getchar();
    while(i<'0'||i>'9'){if(i=='-') f=-1; i=getchar();}
    while(i>='0'&&i<='9') ans=(ans<<3)+(ans<<1)+i-'0',i=getchar();
    ans*=f;
}

int n,m,maxx,maxy;
int x[N],y[N],subx[N],suby[N];
int f[Q],g[Q],cnt[N];

inline int lowbit(int x)
{
    return x&-x;
}

void add(int x,int a,int *t)
{
    while(x<=n) {
	t[x]+=a;
	x+=lowbit(x);
    }
}

int check(int x,int *t)
{
    int ans=0;
    while(x){
	ans+=t[x];
	x-=lowbit(x);
    }
    return ans;
}

int main()
{
    int size; in(n);
    for(int i=1;i<=n;++i) {
	in(x[i]),in(y[i]);
	subx[i]=x[i],suby[i]=y[i];
    }

    sort(subx+1,subx+1+n);
    size=unique(subx+1,subx+1+n)-subx-1;
    for(int i=1;i<=n;i++) x[i]=lower_bound(subx+1,subx+1+size,x[i])-subx;

    sort(suby+1,suby+1+n);
    size=unique(suby+1,suby+1+n)-suby-1;
    for(int i=1;i<=n;i++) y[i]=lower_bound(suby+1,suby+1+size,y[i])-suby;

    for(int i=1;i<=n;i++) {
	int sum=Min(check(x[i],f),check(y[i],g));
	cnt[sum]++;
	add(x[i],1,f),add(y[i],1,g);
    }
    for(int i=0;i<n;++i) printf("%d\n",cnt[i]);
    return 0;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

posted @ 2018-09-02 19:36  real_l  阅读(581)  评论(0编辑  收藏  举报