首页 > 代码库 > TreeArray2352
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;
}
TreeArray2352