TreeArray2352

题意快速理解:给出n个平面二维坐标,对于每个坐标,如果这个坐标跟(0,0)形成的矩形内包含的点数为 k (包含边界,但不包含坐标本身),那么这个坐标就是 level k。输出level 0 - n-1的点数分别是多少。

范围可以从0开始变化,如果要使用树状数组的话那么lowbit(0)就等于0,也就是说tree[0]不管辖其他元素,这显然是不合理的,树状数组中的每个元素至少含有它本身的一个值,这就是树状数组的下标为什么从1开始的原因。处理的办法也是相当的简单,横坐标平移一个单位即可,这样肯定不改变星星的位置关系的

#include <stdio.h>

#include <string.h>

#define MAXN

int level[15005];    //下标为等级数

int tree[32005];     //下标为横坐标

int N;

int lowbit(int x)

{

return x & -x;

}

void modify(int x)

{

int i;

for (i=x; i<=32004; i += lowbit(i))

tree[i] += 1;//tree数组表示节点个数,在x位置又多一个节点,需要更改x以及父节点的节点个数

}

int Sum(int x)

{

int i,sum = 0;

for (i=x; i>=1; i -= lowbit(i) )

sum += tree[i];

return sum;

}

int main()

{

int i,x,y;

memset(tree,0,sizeof(tree));

memset(level,0,sizeof(level));

scanf("%d",&N);

for (i=1; i<=N; i++)

{

scanf("%d%d",&x,&y);

x++;                  //平移处理

level[Sum(x)]++;

///先修改,再求和,这样可以不把自己算进去求和

//大小为x的节点个数加1,用sum求出[1,x]区间的节点总个数

//因为输入是按y坐标升序的,因此第i+1个节点只可能包含i节点(在x方向也满足条件的情况下:xi<=xi+1),而不会第i+1被第i包含,因为Y方向前者更大。因此后来的节点只需要考虑前来的节点是否被该节点包含即可,对于第i+1节点,只需要判断前i个节点中X方向比i+1小的即可,即统计[1,x]的点数,统计之后,等级为sum(1,x)的节点多了一个(第i+1)。另外统计等级时候,自己包含自己的情况不算

///另外这里给的数据是Y按增序排列,如果没有,那么要懂得自己快排一次,之后用树状数组解决。

modify(x);

}

for (i=0; i<N; i++)

printf("%d\n",level[i]);

return 0;

}

时间: 2024-08-29 20:29:22

TreeArray2352的相关文章