zoukankan      html  css  js  c++  java
  • 平衡树维护动态凸包

    codeforces70D

    有两种操作, 1 x y   将(x,y)加入当前的点集合中。 2 x y  询问(x,y)是否在当前点集形成的凸包内。

    即我们要动态的维护凸包,将凸包分为上凸包和下凸包,然后将上凸包关于x轴对称一下, 那么只要维护两个下凸包。

    考虑用平衡树(为了让x有序)来维护凸包,插入一个点时,判断是否在下凸包的下方,如果是则插入且不断往两边删点,直到所有的点都满足凸包的定义为止。

    如下图,插入点p5时,不断判断p5两边的点是否满足凸包的定义。

    明显p2不满足。所有新的凸包是由点p1,p5,p3,p4组成。

    代码里面要注意的是就是如果下凸包里面最左边或者最右边有点 (1,0), 那么新加入的点如果是(1,y),y>0, 那么该点不用加入下凸包,因为该点会加入上凸包的。

      1 #include <iostream>
      2 #include <map>
      3 #include <vector>
      4 #include <stdio.h>
      5 using namespace std;
      6 typedef struct Point{
      7     double x,y;
      8     Point(){}
      9     Point(double x, double y):x(x),y(y){}
     10 }Vector;
     11 Vector operator+(const Vector &a, const Vector &b){
     12     return Vector(a.x+b.x, a.y+b.y);
     13 }
     14 Vector operator-(const Vector &a, const Vector &b){
     15     return Vector(a.x-b.x,a.y-b.y);
     16 }
     17 double Cross(const Vector &a, const Vector &b){
     18     return a.x * b.y - b.x * a.y;
     19 }
     20 
     21 map<int,int> convex[2];
     22 map<int,int>::iterator l,r,l2,r2;
     23 bool isIn(map<int,int>&ma, int x, int y){
     24     if(ma.size()==0) return false;
     25     if(ma.find(x)!=ma.end()) return y >= ma[x];
     26     if(x < (ma.begin()->first) || ((--ma.end())->first) < x) return false;
     27     l = r = ma.lower_bound(x);
     28     l--;
     29     Point L(l->first,l->second);
     30     Point R(r->first,r->second);
     31     Point now(x,y);
     32     return Cross(R-L,now-L) >= 0;
     33 }
     34 void insert(map<int,int> &ma, int x, int y){
     35     if(isIn(ma,x,y))return;
     36     ma[x] = y;
     37     r  = ma.upper_bound(x);
     38 
     39     if(r!=ma.end()){
     40         r2 = r;
     41         r2++;
     42         while(r2!=ma.end()){
     43             Point R(r->first,r->second);
     44             Point R2(r2->first,r2->second);
     45             Point now(x,y);
     46             if(Cross(R-now,R2-now)<0){
     47                 ma.erase(r);
     48                 r = r2;
     49                 r2++;
     50             }
     51             else
     52                 break;
     53         }
     54 
     55     }
     56     l  = ma.lower_bound(x);
     57     if(l==ma.begin()){
     58        return;
     59     }
     60     l--;
     61     if(l==ma.begin())
     62         return;
     63     l2 = l;
     64     l2--;
     65     while(l!=ma.begin()){
     66         Point L(l->first,l->second);
     67         Point L2(l2->first,l2->second);
     68         Point now(x,y);
     69         if(Cross(L2-now,L-now)<0){
     70             ma.erase(l);
     71             l = l2;
     72             l2--;
     73         }
     74         else{
     75             break;
     76         }
     77     }
     78 
     79 }
     80 
     81 int main()
     82 {
     83     int n;
     84     scanf("%d",&n);
     85     for(int i=1;i<=n;++i){
     86         int x,y,type;
     87         scanf("%d%d%d",&type,&x,&y);
     88         if(type==1){
     89             insert(convex[0],x,y);
     90             insert(convex[1],x,-y);//x轴对称一次,把上凸包变成下凸包
     91             //printf("%d %d
    ",convex[0].size(),convex[1].size());
     92         }
     93         else{
     94             //在下凸包的上方
     95             bool ans1 = isIn(convex[0],x,y);
     96             //在上凸包的下方
     97             bool ans2 = isIn(convex[1],x,-y);
     98             if(ans1&&ans2){
     99                 puts("YES");
    100             }
    101             else{
    102                 puts("NO");
    103             }
    104         }
    105 
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    io
    api 类库
    文档生成工具
    数据存储
    uml vs2010
    IE,firefox下jquery获取一组checkbox选中值的问题
    如何通过Jquery简单又快速的获取一组radio的取值呢?
    WCF重载的方式
    Jquery文本框赋值
    Jquery以name获取值
  • 原文地址:https://www.cnblogs.com/justPassBy/p/5181248.html
Copyright © 2011-2022 走看看