由于坐标按照y增序给出,所以当前的y一定是最大值(一定是最高的一个),所以我们只需考虑x坐标,看看前面有多少个星星横坐标是<=xi的,这就是求横坐标在1~xi之间有多少个星星,也就是求一个前缀和。
用一个数组表示每一个横坐标下当前有多少个星星,再求一下1~xi的前缀和(即求多少个星星的横坐标比它小),每多一个星星的话,就在xi处加上1,表示这个坐标中又多了一个星星。
因此我们有两个操作:
① 给某个坐标加上1
② 询问某一个前缀和
这就是树状数组的经典操作了。
注:树状数组中存的是xi前面有多少个星星,因此,每次枚举完要把当前的这个星星加进去
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 32010;
int tr[N], level[N];
int n;
int lowbit(int x)
{
return x & (-x);
}
void add(int x)
{
for (int i = x; i < N; i += lowbit(i)) tr[i] ++;
}
int sum(int x)
{
int res = 0;
for (int i = x; i > 0; 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);
}
for (int i = 0; i < n; ++ i) cout << level[i] << endl;
return 0;
}