zoukankan      html  css  js  c++  java
  • poj 2352 Stars 数星星 详解

    题目:

    poj 2352 Stars 数星星

    题意:已知n个星星的坐标。每个星星都有一个等级,数值等于坐标系内纵坐标和横坐标皆不大于它的星星的个数。星星的坐标按照纵坐标从小到大的顺序给出,纵坐标相同时则按照横坐标从小到大输出。 (0 <= x, y <= 32000) 要求输出等级0到n-1之间各等级的星星个数。

    分析:

      这道题不难想到n平方的算法,即从纵坐标最小的开始搜,每次找它前面横坐标的值比它小的点的个数,两个for循环搞定,但是会超时。

      所以需要用一些数据结构去优化,主要是优化找 横坐标比它小的点的个数 这里可以用线段树维护。我设sumv的意义是,从L到R(L,R代表横坐标的值)范围内的横坐标的个数。它的左儿子是L到M内的个数,右儿子是M+1到R内的个数。叶节点当L=R是,就是横坐标为L的点的个数。最后用vis数组记录每个等级的数量即可。

      我一开始的做法是先输入完,然后直接构造所有节点的线段树,但是这样就不能同时判断纵坐标的大小,调试了好久,发现是错误的。

      由于题目是按照纵坐标的大小,从小到大,同时横坐标从小到大给出的,因此,在一边输入的时候一个点一个点构造线段树就 不用 判断纵坐标的大小。所以只要维护一个横坐标的线段树,在输入的时候一边输,一边查询,一边更新,这样就可以了。在更新的时候,插入数据的方法是从根节点往下一点点更新,查询的方法就是普通的线段树查询。但还有一个小问题:在输入的时候你不能知道线段树的大小是多少,因为你不知道在整个数据中最大的那个横坐标。那我们只好慷慨一点,范围直接用maxn(32000),虽然处理小数据时浪费了点空间,但其实没事的。

      查询和更新的时间复杂度都是logn。总算法的时间复杂度O(nlogn)。

     

    附上代码:

     

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 const int maxn=40010;
     5 
     6 int X[maxn],Y[maxn],n,sumv[maxn*4];
     7 int vis[maxn];
     8 int p;
     9 void update(int o,int L,int R)
    10 {
    11     if(L==R) sumv[o]++;
    12     else 
    13     {
    14         int M=(L+R)/2;
    15         if(p<=M) update(o*2,L,M);
    16         else update(o*2+1,M+1,R);
    17         sumv[o]++;
    18     }
    19 }
    20 
    21 int ans;
    22 void query(int o,int L,int R)
    23 {
    24     if(R<=p) ans+=sumv[o];
    25     else if(p<L) return;
    26     else
    27     {
    28         int M=(L+R)/2;
    29         query(o*2,L,M);
    30         query(o*2+1,M+1,R);
    31     }
    32 }
    33 
    34 int main()
    35 {
    36     cin>>n;
    37     for(int i=1;i<=n;i++)
    38     {
    39         cin>>X[i]>>Y[i];
    40         p=X[i],ans=0;
    41         query(1,0,maxn);
    42         vis[ans]++;
    43         update(1,0,maxn);
    44     }
    45     for(int i=0;i<=n-1;i++) cout<<vis[i]<<endl;
    46     return 0;
    47 }

     

  • 相关阅读:
    Java 位运算(移位、位与、或、异或、非)
    解决Android Studio 2.2.3中添加.cpp .h文件在Project->Android无法显示,无法正常编译问题。
    [ACM] HDU 5083 Instruction (模拟)
    Vbox视图热键
    Android Drawable 与 LayerList综合汇总
    数学之路-python计算实战(14)-机器视觉-图像增强(直方图均衡化)
    HDU 2896 病毒侵袭 AC自己主动机题解
    对团队中“这是某某某的问题”引起的思考
    杭电 2201
    三层架构
  • 原文地址:https://www.cnblogs.com/frankscode/p/6240097.html
Copyright © 2011-2022 走看看