分析:
这道题考的是树状数组的应用
- 题目要求求某一个点(x,y)左下方星星的个数(不包括自己),且星星按y坐标增序给出,y 坐标相同的按x坐标增序给出,因此对于每个新来的点(x,y),y是当前纵坐标的最大值,只需要求[1,x]中星星出现的数量即可
- 每次新来的点,进行树状数组的单点修改操作
- 注意:
树状数组的下标都是从1开始,题目中x的范围【0,32000】因此将x变为x+1,相对位置不变
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 32010;
int n;
int tr[N];
int level[N];//等级
int lowbit(int x)
{
return x & -x;
}
void add(int x,int v)
{
for(int i=x;i<=N;i+=lowbit(i)) tr[i]+=v;//星星按 y 坐标增序给出,y 坐标相同的按 x 坐标增序给出
//所以此时y0最大,这个点所处的级数就是之前输入坐标中【1~x0】坐标数目
}
int sum(int x)
{ int res=0;
for(int i=x;i;i-=lowbit(i)) res+=tr[i];
return res;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
int x,y;
cin>>x>>y;
x++;//树状数组的下标是从一开始的;
level[sum(x)]++;
//将当前坐标加入数组
add(x,1);
}
for(int i=0;i<n;i++) printf("%d\n",level[i]);
return 0;
}