POJ_2352
由于我们在读入数据的时候已知了前面星星的个数,实际上再减去当前星星右边的星星的数量即可,因此我们可以用一个线段树存储横坐标区间里的星星个数,每读入一个星星就修改并查询一次,并记录level即可。
#include<stdio.h>
#include<string.h>
#define MAXD 32010
#define MAXN 15010
int M, N, tree[4 * MAXD], num[MAXN];
void init()
{
for(M = 1; M < 32003; M <<= 1);
memset(tree, 0, sizeof(tree));
memset(num, 0, sizeof(num));
}
void solve()
{
int i, j, k, x, y, s, t, level;
for(i = 0; i < N; i ++)
{
scanf("%d%d", &x, &y);
x = x + M + 1;
s = x, t = 32001 + M + 1;
tree[x] ++;
for(; x ^ 1; x >>= 1)
tree[x >> 1] ++;
level = 0;
for(; s ^ t ^ 1; s >>= 1, t >>= 1)
{
if(~s & 1)
level += tree[s ^ 1];
if(t & 1)
level += tree[t ^ 1];
}
level = i - level;
num[level] ++;
}
for(i = 0; i < N; i ++)
printf("%d\n", num[i]);
}
int main()
{
while(scanf("%d", &N) == 1)
{
init();
solve();
}
return 0;
}