.............................................................................................................................................................................................................................................................
[题目大意]
给定一个星座的直角坐标图,每个星星都有一个坐标值(x,y)(0<=X,Y<=32000);其中输入中的y是不下降的。给出N(1<=N<=15000)个星星
的坐标,输出等级分别为0,1,2 3,4,...的星星的个数。星星的等级的定义是:如果有m个星星的坐标(x,y)均小于等于该星星的坐标(x0,y0)则该星星的等级为m。
Sample Input
5
1 1
5 1
7 1
3 3
5 5
Sample Output
1 (等级为0的星星的个数)
2 (等级为1的星星的个数)
1 (等级为2的星星的个数)
1 (等级为3的星星的个数)
0 (等级为4的星星的个数)
[题目详解]
用树状数组,不用管y坐标(因为已经是升序,后边的星星不影响前边星星的等级),用lev(n)来统计等级为n的星星个数,但是千万注意树状数组需要数组以1为首项,由于坐标有0,所以每次需要给x坐标+1。
如图:
等级为0的星星的个数1 坐标(1,1)
等级为1的星星的个数2 坐标 (3,3),(5,1)
等级为2的星星的个数1 坐标 (7,1)
等级为3的星星的个数1 坐标 (5,5)
等级为4的星星的个数0 没有
在poj上wrong answer、Time Limit Exceeded、Output Limit Exceeded加一起10+了,整整一天看了好多人的代码和解题报告,一开始数组开的太小,树状数组是从1开始的,坐标上有0,必须+1。
.............................................................................................................................................................................................................................................................
代码:
#include<stdio.h>
#include<string.h>
#define MAX 32005 //题目是32000,不能小于32000
int tree[MAX],n;
int asn[MAX];
int lowbit(int idx)
{
return idx&(-idx);
}
void update(int idx,int val)
{
while(idx<=MAX)
{
tree[idx]+=val;
idx+=lowbit(idx);
}
}
int sum(int idx)
{
int sum=0;
while(idx>0)
{
sum+=tree[idx];
idx-=lowbit(idx);
}
return sum;
}
int main()
{
int t,x,y,i;
while(scanf("%d",&n)!=EOF)
{
memset(tree,0,sizeof(tree));
memset(asn,0,sizeof(asn));
for(i=1;i<=n;i++)
{
scanf("%d %d",&x,&y);
x=x+1;
update(x,1);
asn[sum(x)-1]++;
}
for(i=0;i<n;i++)
{
printf("%d\n",asn[i]);
}
}
return 0;
}