首页 > 代码库 > TreeArray2352

TreeArray2352

 

 

题意快速理解:给出n个平面二维坐标,对于每个坐标,如果这个坐标跟(0,0)形成的矩形内包含的点数为 (包含边界,但不包含坐标本身),那么这个坐标就是 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