题目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 }