题目http://acm.hdu.edu.cn/showproblem.php?pid=1541

n个星星的坐标,问在某个点左边(横坐标和纵坐标不大于该点)的点的个数有多少个,输出n行,每行有一个数字,代表左下角个点数为i( i 从0开始)的点的个数。

首先将横坐标排序,这样就值需要比较纵坐标,可以采用hash的方法记录纵坐标为 i 的个数,每枚举到一个点hash加一,然后树状数组求纵坐标 不大于该点的

个数。值得注意的是树状数组是由 1 开始的,而题目可以从0开始,会超时,加一就好。

具体看代码。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 struct point {
 6     int x,y;
 7 };
 8 point a[32010];
 9 int has[32010],ha[32010];
10 bool cmp(point a,point b){
11     if (a.x==b.x) return a.y<b.y;
12     return a.x<b.x;
13 }
14 void add(int x,int y){
15     while (x<=32000) {
16         has[x]+=y;
17         x+=(x&(-x));
18     }
19 }
20 int getsum(int x){
21     int ans=0;
22     while (x>0) {
23         ans+=has[x];
24         x-=(x&(-x));
25     }
26     return ans;
27 }
28 int main()
29 {
30     int n,i;
31     while (~scanf("%d",&n)){
32     memset(has,0,sizeof(has));
33     memset(ha,0,sizeof(ha));
34     for (i=1;i<=n;i++)
35         scanf("%d %d",&a[i].x,&a[i].y),a[i].x++,a[i].y++;
36     sort(a+1,a+n+1,cmp);
37     //printf("%d\n",getsum(a[1].y));
38     for (i=1;i<=n;i++){
39         ha[getsum(a[i].y)]++;
40         add(a[i].y,1);
41     }
42     for (i=0;i<n;i++) printf("%d\n",ha[i]);
43     }
44     return 0;
45 }

 

posted on 2016-03-17 22:01  蜘蛛侦探  阅读(168)  评论(0编辑  收藏  举报