.............................................................................................................................................................................................................................................................
[题目大意]
给定一个星座的直角坐标图,每个星星都有一个坐标值(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; }