1144数星星(树状数组)

来源:互联网 发布:windows启动盘 编辑:程序博客网 时间:2024/05/17 01:59

1144 数星星

该题有题解

时间限制:564MS  内存限制:65536K
提交次数:193 通过次数:43

题型: 编程题   语言: G++;GCC

Description

天文学家们喜欢观察星星。它们把每颗星星看成一个点,并把每颗星星左下方(即横坐标和纵坐标都不比它大)的星星颗数作为它的等级值。现给出所有星星(星星个数为N)的坐标,计算并输出指定编号的星星的等级。注意:不存在相同坐标的星星



输入格式

第一行为N后N行为编号为1到N的星星的坐标(坐标用整数)此后是M后一行是M个星星的编号N<=100000M<=1000坐标范围0<=x,y<=1000000


输出格式

要求依次输出这M个星星的等级,一行一个


输入样例

50 02 03 01 12 224 5


输出样例

13该题为poj上star的变形,也没变多少。求一个星星的等级,也就是求该星星的下面和左面一共有多少个星星。可以现将所有星星的按坐标排序,按y轴先排或者按x轴先排都可以。若按Y轴排好序后,我们只需要知道该所求星星的左边有多少个星星就行了,也就是有多少个x比它小的。这样,求之前所有的x,问题就转化为求数列的前缀和,我们可以用树状数组去解决。下面是一些关于树状数组的博客http://www.cnblogs.com/huangxincheng/archive/2012/12/05/2802858.htmlhttp://blog.chinaunix.net/uid-22263887-id-1778936.htmlhttp://www.cnblogs.com/zhj5chengfeng/archive/2013/03/20/2965833.htmlhttp://www.cnblogs.com/Hilda/archive/2012/08/08/2628426.htmlhttps://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 1000005using 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]);    }}


0 0
原创粉丝点击