题目大意:
给你星星的坐标(y递增,若y相等,x递增),每个星星都有一个等级,规定它的等级就是在它左下方的星星的个数。输入所有星星后,依次输出等级为0到n-1的星星的个数。
解题思路:
统计x前面比它小的星星的个数。注意的是:给的点的坐标是从0开始的,树状数组下标为0的位置不可用,所以我们需要在输入x坐标时+1。
因为本题给出的数据就是已经按照y从小到大排好序的,也就是说,当前读到一个点的时候,当前点的y坐标肯定比已经读入的大,或者等于。就算是等于的话,也是x坐标比我当前点的x坐标小,所以我们每次只要算x坐标比我们小的就行了 。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 32010
int ans[maxn];
int n;
int c[maxn];
int lowbit(int x)
{
return x & -x;
}
void add(int i,int val)// Add操作,将第i个元素增加val,那么他的父节点也要增加+
{
while(i<=maxn)
{
c[i]+=val;
i+=lowbit(i);//i的父节点
}
}
int sum(int i)
{
int s=0;
while(i>0)
{
s+=c[i];
i-=lowbit(i);//I的前驱
}
return s;
}
int main()
{
scanf("%d",&n);
int x,y;
for(int i=1;i<=n;++i)
{
scanf("%d%d",&x,&y);
x+=1;
ans[sum(x)]++;
add(x,1);
}
for(int i=0;i<n;++i)
printf("%d\n",ans[i]);
return 0;
}