zoukankan      html  css  js  c++  java
  • 数星星

    题目描述

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

    给定星星的位置输出各级星星的数目。
    给定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
    ",cnt[i]);
        return 0;
    }
    

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

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

  • 相关阅读:
    [nodejs] web后端开发时, 用hapi/Joi对前端提交的数据进行校验--随笔
    [C++]类的空指针调用成员函数后,会发生什么事?
    赵家庙保险队大队长【永远置顶】
    NX二次开发-NXOpen C# OpenFileDialog弹出选择文件对话框
    NX二次开发-NXOpen C# string转tag
    NX二次开发-UFUN创建扫掠UF_MODL_create_sweep
    NX二次开发-NXOPEN C# WinForm点构造器UF.Ui.PointConstruct和UI加锁解锁UF.Ui.LockUgAccess
    vue 移动端手写手机验证码登录
    java--Scanner扫描器
    react中this.props.history实现跳转页面的使用方法
  • 原文地址:https://www.cnblogs.com/real-l/p/9574918.html
Copyright © 2011-2022 走看看