题意:给你n个点代表n个星星,以该点为起点向x,y轴作垂线,会得到一个矩形,这个矩形里面所包含的星星数(不包括它本身)称为该星星的等级,要求输出在0-n-1等级各有多少个星星。注意给出的点的顺序很有讲究,是按照y坐标升序给出,如果y坐标相同,则按照x坐标升序给出。

思路

可以运用前缀和的思想,因为本身输入是按y坐标升序给出的,已经满足了两个条件之一,那么只要查询这个输入之前有多少个星星,所以要记录每个坐标x上有几颗星星。

这里要注意x不能为0,否则会死循环,所以输入的时候x++,add()中x<=MAXN+1。

代码

int n;
int d[32010];//记录星星在x=i有多少颗
int lev[15010];
int lowbit(int x)
{
    return x&(-x);
}
int query(int x)//查询前缀和
{
    int res=0;
    while(x)
    {
        res+=d[x];
        x-=lowbit(x);
    }
    return res;
}
void add(int x,int v)//单点修改
{
    while(x<=32001)//这里应该小于32001(因为横坐标+1)
    {
        d[x]+=v;
        x+=lowbit(x);
    }
}
int main()
{
    int x,y;
    scanf("%d",&n);
    memset(d,0,sizeof(d));
    memset(lev,0,sizeof(lev));
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        x++;//x不能为0,lowbit(0)=0会造成死循环
        //printf("(%d)",query(x));
        lev[query(x)]++;
        add(x,1);
    }
    for(int i=0;i<n;i++)
        printf("%d\n",lev[i]);
    return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

bzoj1878 离线处理+树状数组 Previous
树状数组 Next