zoukankan      html  css  js  c++  java
  • 1144 数星星 (树状数组)

    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
    



     

    作者

     admin

      要求某个星星的的左下方的星星的个数,就是求出在整组数据中x坐标和y坐标都小于等于该星星坐标的其他星星的个数。可能会想到直接套二维的树状数组,不过x,y最大为

    1000000,开不下这么大的内存。 所以 把这道题"降维"先:将所有的星星先y坐标从小到大排序,如果y相同的就把x坐标较小的排前面;排完序后的数组中,对于第i个星星,扫一遍它前面的
    i-1个星星,其中x坐标小于等于它的个数,就是位于它左下方的星星个数。   这里求前面i-1个元素的和可以用树状数组。用个循环从1~n更新;另开一
    个大小为max_x(数据中最大的x坐标)的数组bit[]初始化为0。 因为数组已经按上面说的方法排过序了,所以所以第1个更新的元素star[1]肯定是不会有其他星星在它左下角(它的y和x坐标都是最小的了),
    然后更新它updata(star[1].x),就是把bit[star[1].x] 加1后往后更新。以此类推,更新后面的元素时,他们的y坐标肯定是比前面的元素大的,所以只要计算bit[]中前i-1个所有元素的和就行了。
    另外,题目要查询的是原数组中的编号,但程序中又需要对其进行排序。所以可以用结构体来存储星星的信息,里面再加一个变量pos来标记该星星的原下标是什么。 (PS:要AC这题,因为数据比较水,其
    实可以在统计前面i-1个元素中x坐标比其小的个数 的这一步中可以暴力扫一遍。。。复杂度O(mn)...

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <cstdlib>
     7 #include <cctype>
     8 #include <queue>
     9 #include <stack>
    10 #include <map>
    11 #include <vector>
    12 #include <set>
    13 #include <utility>
    14 #define ll long long
    15 #define inf 0x3f3f3f3f
    16 #define MAX_N 100000
    17 #define MAX_X 1000000
    18 using namespace std;
    19 
    20 typedef struct node
    21 {
    22     int x,y;
    23     int p; //因为要对数组排序而询问的是原数组下标的答案,所以用个变量p来标记该元素的原下标
    24 } node;
    25 node star[MAX_N+5];
    26 bool cmp(node a,node b) //按y大小升序来排序,y相同时把x较小的排前面
    27 {
    28     if(a.y!=b.y)
    29         return a.y<b.y;
    30     else
    31         return a.x<b.x;
    32 }
    33 int n,m,maxn;
    34 int ans[MAX_N+5]; //ans[]数组存储每个星星的等级
    35 int bit[MAX_X+5]; //树状数组中的统计和的数组
    36 int sum(int pos)
    37 {
    38     int res=0;
    39     while(pos)
    40     {
    41         res+=bit[pos];
    42         pos-=(pos&-pos);
    43     }
    44     return res;
    45 }
    46 void updata(int pos,int value)
    47 {
    48     while(pos<=maxn)
    49     {
    50         bit[pos]+=value;
    51         pos+=(pos&-pos);
    52     }
    53 }
    54 int main()
    55 {
    56     //freopen("input.txt","r",stdin);
    57     memset(bit,0,sizeof(bit));
    58     scanf("%d",&n);
    59     maxn=-1;
    60     for(int i=1; i<=n; i++)
    61     {
    62         scanf("%d%d",&star[i].x,&star[i].y);
    63         star[i].x++;    //在树状下标不能有0,否则会死循环!
    64         star[i].y++;   //所以然横纵坐标都+1
    65         star[i].p=i;
    66         if(star[i].x>maxn)
    67             maxn=star[i].x;  //更新最大的x坐标
    68     }
    69     sort(star+1,star+n+1,cmp);//以y坐标升序来sort
    70     //
    71     for(int i=1; i<=n; i++)
    72     {
    73         ans[star[i].p]=sum(star[i].x); //计算位于其左下方的星星个数
    74         updata(star[i].x,1);  //更新bit[]数组
    75     }
    76     //
    77     scanf("%d",&m);
    78     while(m--)
    79     {
    80         int temp;
    81         scanf("%d",&temp);
    82         printf("%d
    ",ans[temp]);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    四个通用分页存储过程(来源于www.codeproject.com)
    C#2.0 print winform 打印窗体数据试试
    C# 2.0 Graphics 画雪人
    [转]Asp.Net 上传大文件专题(1)概述:上传大文件的难点
    [转]Asp.Net 上传大文件专题(2)页面生成流程
    [转]C# 调用sql 2000存储过程
    [转]Asp.Net 上传大文件专题
    [转]Asp.Net 上传大文件专题(3)从请求流中获取数据并保存为文件[下]
    c#中调用Ffmpeg转换视频格式的问题
    [转]Asp.Net 上传大文件专题(3)从请求流中获取数据并保存为文件[上]
  • 原文地址:https://www.cnblogs.com/geek1116/p/5566709.html
Copyright © 2011-2022 走看看