分析:每个星星的level是它左下区域(包括边界)的星星的个数,由于星星的坐标是先按y的大小,再按x的大小排序的,所以第i个星星之前的星星都不在它的上侧,计算第i个星星的level时只需要统计之前有多少个星星的x坐标小于等于第i个星星的x坐标(即不在它的上侧)。如果用a[j]来记录下前i-1个星星中x坐标为j的个数,那个第i个星星的level就会等于a[0]+a[1]+...+a[x]。每次计算完第i个星星的level后,都要去更新a[x]的值,这是一个动态连续和问题,可以用二叉索引树(树状数组)。
#include<stdio.h>
#include<string.h>
const int maxl = 32000 + 5;
const int maxn = 15000 + 5;
int c[maxl], level[maxn];
int n;
int lowbit(int x) {
return x & (-x);
}
int sum(int x) {
int ret = 0;
while (x > 0) {
ret += c[x];
x -= lowbit(x);
}
return ret;
}
void add(int x, int d) {
while (x <= maxl) {
c[x] += d;
x += lowbit(x);
}
}
int main() {
memset(c, 0, sizeof(c));
memset(level, 0, sizeof(level));
int x, y;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &x, &y);
++x; // 坐标x是从0开始的
level[sum(x)]++;
add(x, 1);
}
for (int i = 0; i < n; i++) {
printf("%d\n", level[i]);
}
return 0;
}