题目链接
题意
给你n个星星的坐标,已经按y坐标排序(y递增,若y相等,x递增),每个星星都有一个等级,规定它的等级就是在它左下方的星星的个数。输入所有星星后,依次输出等级为0到n-1的星星的个数。
思路
因为输入都是已经按y坐标排好序的,所以本题就是统计x前面比它小的星星的个数,符合树状数组最基本的应用。
注意:树状数组下标为0的位置不可用,所以我们需要在输入x坐标时+1.
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=32010;
int cnt[maxn];//记录结果
int bit[maxn];//树状数组
int n;//叶子结点数目
int lowbit(int x)
{//返回二进制数的最后一位1
return x&(-x);
}
int sum(int x)
{//返回a[1]~a[x]的和
int res=0;
while(x)
{
res+=bit[x];
x-=lowbit(x);
}
return res;
}
void add(int x,int v)
{//实现对a[x]+v的修改
while(x<=maxn)//注意这里不能写成x<=n
{
bit[x]+=v;
x+=lowbit(x);
}
}
int main()
{
int x,y,i;
while(cin>>n)
{
memset(bit,0,sizeof(bit));
memset(cnt,0,sizeof(cnt));
for(i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
int tmp=sum(x+1);
//加入x+1,是为了避免0,树状数组的下标不能为0
cnt[tmp]++;
add(x+1,1);
}
for(i=0;i<n;i++)
printf("%d\n",cnt[i]);
}
return 0;
}