1144 数星星
该题有题解
时间限制:564MS 内存限制:65536K
提交次数:193 通过次数:43
题型: 编程题 语言: G++;GCC
Description
天文学家们喜欢观察星星。它们把每颗星星看成一个点,并把每颗星星左下方(即横坐标和纵坐标都不比它大)的星星颗数作为它的等级值。 现给出所有星星(星星个数为N)的坐标,计算并输出指定编号的星星的等级。 注意:不存在相同坐标的星星
输入格式
第一行为N 后N行为编号为1到N的星星的坐标(坐标用整数) 此后是M 后一行是M个星星的编号 N<=100000 M<=1000 坐标范围0<=x,y<=1000000
输出格式
要求依次输出这M个星星的等级,一行一个
输入样例
5 0 0 2 0 3 0 1 1 2 2 2 4 5
输出样例
1 3 该题为poj上star的变形,也没变多少。求一个星星的等级,也就是求该星星的下面和左面一共有多少个星星。可以现将所有星星的按坐标排序,按y轴先排或者按x轴先排都可以。 若按Y轴排好序后,我们只需要知道该所求星星的左边有多少个星星就行了,也就是有多少个x比它小的。 这样,求之前所有的x,问题就转化为求数列的前缀和,我们可以用树状数组去解决。 下面是一些关于树状数组的博客 http://www.cnblogs.com/huangxincheng/archive/2012/12/05/2802858.html http://blog.chinaunix.net/uid-22263887-id-1778936.html http://www.cnblogs.com/zhj5chengfeng/archive/2013/03/20/2965833.html http://www.cnblogs.com/Hilda/archive/2012/08/08/2628426.html https://www.topcoder.com/community/data-science/data-science-tutorials/binary-indexed-trees/#prob 题目代码如下:由于要将星星排序,而排序后又要按原来的下标找到它的位置,可以设置一个结构体 struct bit{ int x,y,z; }; x,y存储坐标,而z存储它在原来序列的坐标。#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define maxn 1000005 using namespace std; int c[maxn],maxx; struct BIT{ int x,y,z; }bit[maxn]; bool cmp(BIT a, BIT b) { if( a.y == b.y) return a.x < b.x; return a.y < b.y; } int lowbit(int i) { return i&(-i); } int sum(int i) { int ans = 0; { while(i) { ans += c[i]; i -= lowbit(i); } } return ans; } void update(int i,int newValue) { while(i<=maxx) { c[i] += newValue; i += lowbit(i); } } int t[maxn], cnt[maxn]; int main() { //freopen("a","r",stdin); int n, m; memset(c,0,sizeof(c)); maxx = 0; scanf("%d", &n); for(int i=0; i<n; i++) { scanf("%d%d", &bit[i].x,&bit[i].y); bit[i].x++; bit[i].y++; bit[i].z = i; if(maxx < bit[i].x) maxx = bit[i].x; } sort(bit,bit+n,cmp); for(int i=0; i<n; i++) { cnt[bit[i].z] = sum(bit[i].x); update(bit[i].x,1); } scanf("%d",&m); for(int i=0; i<m; i++) { scanf("%d", &t[i]); } for(int i=0; i<m; i++) { printf("%d\n", cnt[t[i]-1]); } }