【树状数组】数星星(POJ2352 star…

【树状数组】数星星(POJ2352 star)

Time Limit:1000MS  Memory Limit:65536K
Total Submit:14 Accepted:9

Description

天文学家经常观察星象图。星象图中用平面上的点来表示一颗星星,每一颗星星都有一个笛卡尔坐标。设定星星的等级为其左下角星星的总数。天文学家们想知道星星等级的分布情况。

【树状数组】数星星(POJ2352 <wbr>star)PASCAL

比如上图,5号星星的等级为3(其左下角有编号为1、2、4的星星共三颗)。2号星星和4号星星的等级为1。在上图中只有一颗星星等级为0,两颗星星等级为1,一颗星星等级为2,一颗星星等级为3。
给定一个星象图,请你写一个程序计算各个等级的星星数目。

Input

输入的第一行包含星星的总数N (1<=N<=15000)。接下来N行,描述星星的坐标(X,Y)(X和Y用空格分开,0<=X,Y<=32000)。星象图中的每个点处最多只有一颗星星。所有星星按Y坐标升序排列。Y坐标相等的星星按X坐标升序排列。

Output

输出包含N行,每行一个整数。第一行包含等级0的星星数目,第二行包含等级1的星星数目,依此类推,最后一行包含等级为N-1的星星数目。

Sample Input


Sample Output


Hint

① 对于C/C++的程序员,这个问题的规模比较大,读数据的时候为了避免超时,推荐使用scanf() 取代cin。
② 请将你的程序在 http://poj.org/problem?id=2352 上提交测试是否能通过!

Source

Ural Collegiate Programming Contest 199zhu

 

树状数组

因为数据已按y的升序给出,所以某个点下方的点已记录

现就是利用树状数组记录 某个点左边的点的个数 及 记录了这个点后对这个点右边的影响

直接用就行了

 

只是POJ的数据总不是那么容易过的

题目中说“0<=X,Y<=32000”,当x=0时,用树状数组时就会出现问题,

解决方法是读入后就 inc(x);

 

 

var
 n,i,x,max:longint;
 a:array[1..15010]of longint;
 f:array[1..32010]of longint;
 tot:array[0..15010]of longint;

 

function find(x:longint):longint;
begin
  find:=0;
  while x>0 do
   begin
    inc(find,f[x]);
    x:=x-x and(-x);
   end;
end;

procedure add(x:longint);
begin

 while x<=max do
  begin
   inc(f[x],1);
   x:=x+x and(-x);
  end;
end;

begin
 max:=0;
 read(n);
 for i:=1 to n do begin read(a[i],x); a[i]:=a[i]+1; if a[i]>max then max:=a[i]; end;
 for i:=1 to n do
  begin
  x:=a[i];
  inc(tot[find(x)]);
  add(x);
  end;
 for i:=0 to n-1 do writeln(tot[i]);
end.

你可能感兴趣的:(PASCAL)