Stars
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 27333 | Accepted: 11958 |
Description
Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers want to know the distribution of the levels of the stars.
For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it's formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.
You are to write a program that will count the amounts of the stars of each level on a given map.

For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it's formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.
You are to write a program that will count the amounts of the stars of each level on a given map.
Input
The first line of the input file contains a number of stars N (1<=N<=15000). The following N lines describe coordinates of stars (two integers X and Y per line separated by a space, 0<=X,Y<=32000). There can be only one star at one point of the plane. Stars are listed in ascending order of Y coordinate. Stars with equal Y coordinates are listed in ascending order of X coordinate.
Output
The output should contain N lines, one number per line. The first line contains amount of stars of the level 0, the second does amount of stars of the level 1 and so on, the last line contains amount of stars of the level N-1.
Sample Input
5 1 1 5 1 7 1 3 3 5 5
Sample Output
1 2 1 1 0
Hint
This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.
题意:
有N(1到15000)颗星星,给出每颗星星的x,y(0到32000)坐标。星星以y的递增顺序输入,如果y相等就以x递增的顺序输入。每颗星星都有一个等级,这个等级数是这颗星星左下位置的星星数量,最终统计每一层等级(0到N-1)的数量。
思路:
有一个关键的条件,星星以y的递增顺序输入,如果y相等就以x递增的顺序输入。这样的话,就是说明每输入一颗星星A,这个星星A一定是最高的,但是不一定是最右边的,在以后的每次输入中,不会再有一颗星星B会出现在这颗星星A的左下位置处,因为星星B一定要比A高,但是比A高不一定会在A的右边,但是无论B在左边还是右边,可以确定的一定是B肯定要比A高,那么就可以确定以后的每一颗星星B都不会出现在A的左下位置处,这就说明A的等级不会因为后面出现的星星而改变。
所以,先找出全部星星x坐标的最小值min和最大值max,以[min,max]为界来建立线段树。每次输入一颗星星之前,先统计在[min,x]中有几颗星星,这个星星数就是它的等级数,统计之后再插入这颗星星的x坐标于线段树中。
AC:
#include<stdio.h> #include<string.h> #define M (32000+5) //易错点 typedef struct { int l; int r; int sum; }node; node no[M*4]; int x[M],y[M]; int fin[M],t; void build(int from,int to,int i) { int mid=(from+to)/2; no[i].l=from; no[i].r=to; no[i].sum=0; if(from==to) return; build(from,mid,2*i); build(mid+1,to,2*i+1); } void add(int i,int a) { int mid=(no[i].l+no[i].r)/2; if(no[i].l==no[i].r) { no[i].sum++; return; } if(a<=mid) add(2*i,a); if(a>=mid+1) add(2*i+1,a); no[i].sum=no[2*i].sum+no[2*i+1].sum; } void find(int from,int to,int i) { int mid=(no[i].l+no[i].r)/2; if(from==no[i].l&&to==no[i].r) { t+=no[i].sum; return; } if(from>=mid+1) find(from,to,2*i+1); if(to<=mid) find(from,to,2*i); if(from<=mid&&to>=mid+1) { find(from,mid,2*i); find(mid+1,to,2*i+1); } } int main() { int n; int min,max; while(scanf("%d",&n)!=EOF) { min=M,max=-1; for(int i=1;i<=n;i++) { scanf("%d%d",&x[i],&y[i]); if(x[i]>max) max=x[i]; if(x[i]<min) min=x[i]; } build(min,max,1); memset(fin,0,sizeof(fin)); for(int i=1;i<=n;i++) { t=0; find(min,x[i],1); fin[t]++; add(1,x[i]); } for(int i=0;i<=n-1;i++) printf("%d\n",fin[i]); } return 0; }
总结:
1.题目是多输入;
2.RE了N次,是因为#define M (32000+5)。一开始写成了#define M 32000+5,因为后面数组的大小是M*4,这样的话就是32000+5*4。而事实上我想要的结果是(32000+5)*4,所以要加括号。要细心。
相关推荐
### POJ 2352 Stars - 树状数组与线段树实现 #### 题目背景 POJ 2352 Stars 是一道经典的算法题目,它提供了使用树状数组或线段树来解决的可能性。这两种数据结构都是为了高效处理区间查询问题而设计的。在这篇...
- **逆序对计数**:线段树可以用来计算数组中的逆序对数量,如题目2352Stars。 - **求第k小/大数**:线段树可以扩展到支持查询区间内的第k小(大)数,如题目2761Feed the dogs。 - **区间染色问题**:线段树可以...
在POJ2482 Stars in Your Window问题中,由于数值范围很大,需要先离散化处理,然后将二维问题转化为一维线段树。通过插入和删除操作,可以解决求前k项最大和的问题。此外,要注意处理边界条件,如输入数据可能在...
以每个星星为中心,得到可以罩住它的矩形的左下角的范围,这些范围内的点增加星星亮度,由于落在框上的点不算,框不一定要整数起点,可另左下落在框上算。求亮度和最大的点即可。...每次用线段树更新和求最大值。
线段树 RMQ LCA+RMQ SB-Tree 数论 生成紧凑素数表 分解质因子 最大公约数 a^b mod n 扩张欧几里德算法 素数表质因子分解 Stirling公式 中国剩余定理 欧拉数(递推法) 欧拉数(公式法) 十进制转负进制 ...
线段树是一种数据结构,可以支持区间查询和更新操作,其时间复杂度为O(logn)。而树状数组,又称斐波那契堆,同样可以高效地处理区间查询和单点修改问题,它的核心思想是维护一个数组,并通过前缀和快速计算区间和。 ...
此类问题可以通过构建线段树来高效地处理区间更新和查询操作。 #### 动态规划 动态规划是一种通过将问题分解为子问题,然后保存子问题的解来避免重复计算的方法。 **案例分析:Pku1141—Brackets Sequence** ...
1038 T9 无聊题,单词树 1330 DNA Translation 无聊题 1335 Letter Sequence Analysis 无聊题 1099 HTML 无聊题 1243 URLs 无聊题 1540 Censored! 经典题!强烈推荐! 1511 Word Puzzles 没有完美...
1038 T9 无聊题,单词树 1330 DNA Translation 无聊题 1335 Letter Sequence Analysis 无聊题 1099 HTML 无聊题 1243 URLs 无聊题 1540 Censored! 经典题!强烈推荐! 1511 Word Puzzles 没有完美...