思路:
因为直接进行二维前缀和,O(n^2) 别超时,所以用 树状数组为O(n*lg n).
因为输入时保证 一行一行输入,所以只要计算x坐标的增加。图中的A[x] 表示坐标为x 时,当前输入过有多少星星。此数组用 树状数组 表示。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=32010;
int tr[N] ,le[15010];
//树状数组3个常规操作
int lowbit(int x)
{
return x & -x;
}
int sum(int x)
{
int res=0;
for(int i=x;i;i-=lowbit(i)) res+=tr[i];
return res;
}
void add(int x)
{
for(int i=x;i<N;i+=lowbit(i)) tr[i]++; //此处需要注意小于 N 。因为你并不知道后面的 x 有多大,所以开到最大
//1264 题直接小于 n 就可以,因为输入时提前给出数组的长度
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x++;//因为树状数组下标从 1 开始,所以 ++
le[sum(x)]++;//横坐标加了一个 星星,所以星星的级数 ++
add(x);// 加过级数后进行 树状数组 的++,因为刚加的星星不能算到里面
}
for(int i=0;i<n;i++) printf("%d\n",le[i]);
return 0;
}