POJ 2352 Stars【树状数组】
<题目链接>
题目大意:
题目给出n个点,这些点按照y坐标的升序,若y相同,则按照x的升序顺序输入,问,在这些点中,左下角的点的数量分别在0~n-1的点分别有多少个,写出它们的对应点数。
解题分析:
因为所有点是按照y坐标的升序优先给出,所以后面的点y坐标一定大于等于前面的。于是,判断该点前面有多少点满足在该点的“左下角”,只需看前面的点有几个x坐标小于当前点即可,所以,我们只需要对x坐标建一维树状数组即可求解。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int N =15000+10; 7 const int M =32000+10; 8 int tr[M],cnt[N]; 9 int lowbit(int x){return x&(-x);} 10 void add(int i,int val){ 11 while(i<=M){ 12 tr[i]+=val; 13 i+=lowbit(i); 14 } 15 } 16 int sum(int i){ 17 int ans=0; 18 while(i>=1){ 19 ans+=tr[i]; 20 i-=lowbit(i); 21 } 22 return ans; 23 } 24 int main(){ 25 int n; 26 while(scanf("%d",&n)!=EOF){ 27 memset(cnt,0,sizeof(cnt)); 28 memset(tr,0,sizeof(tr)); 29 for(int i=0;i<n;i++){ 30 int x,y; 31 scanf("%d%d",&x,&y); 32 cnt[sum(x+1)]++; //之所以将x+1,是因为树状数组最小下标只能为1,而题目所给的x可能为0 33 add(x+1,1); 34 } 35 for(int i=0;i<n;i++) 36 printf("%d\n",cnt[i]); 37 } 38 return 0; 39 }
2018-10-15
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。