• 动态凸包


    动态凸包,就是每次插入一个点,求新形成的凸包;

    就是给点一个序,然后找到插入点在凸包中的前驱后后继,然后俩边分别维护;

    可以用水平序,也可以用极角序,水平序因为要分别维护上下两个半凸包,而且因为是分别的维护的,不像极角序一样

    可以循环,即最后一个的点的后继就是第一个点,所以极角序相对实现起来简单,但极角有一个问题就是要找一个基准点,如果点都不重复

    那刚开始的点就可以,如果重复的话,在遇到这个点就连极角都求不出了。。。还有一些其他问题,我也不知道,就是做sgu277是一直第二组就WA了;

    但CF70D还是能过的;

    水平序:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<set>
      8 #include<algorithm>
      9 #define make_pair Mk
     10 using namespace std;
     11 typedef long long LL;
     12 typedef pair<int,int> pii;
     13 struct Point{
     14     int x,y;
     15     Point(int a=0,int b=0):x(a),y(b){}
     16     Point operator - (const Point &p)const{
     17         return Point(x-p.x, y-p.y);
     18     }
     19     bool operator < (const Point &p)const{
     20         return x<p.x || (x==p.x && y<p.y);
     21     }
     22 };
     23 LL Cross(const Point &u,const Point &v){
     24     return (LL)u.x*v.y - (LL)u.y*v.x;
     25 }
     26 LL Dot(const Point &u,const Point &v){
     27     return (LL)u.x*v.x + (LL)u.y*v.y;
     28 }
     29 multiset<Point> st1,st2;
     30 multiset<Point> :: iterator it1,it2;
     31 int n;
     32 Point tp[4];
     33 void init(){
     34     sort(tp,tp+3);
     35     st1.clear(); st2.clear();
     36     
     37     st1.insert(tp[0]); st1.insert(tp[2]);
     38     st2.insert(tp[0]); st2.insert(tp[2]);
     39     if (Cross(tp[1]-tp[0], tp[2]-tp[0]) > 0 ){
     40         st1.insert(tp[1]);
     41     }else st2.insert(tp[1]);
     42 
     43 }
     44 bool IsPointOnSeg(const Point &u,const Point &v,const Point &p){
     45     if (Cross(u-p,v-p)==0  && Dot(u-p,v-p)<=0) return 1;
     46     return 0;
     47 }
     48 int  IsInDownConvexHull(const Point &u){
     49     if (st1.count(u)>0) return 1;
     50     it2 = it1 = st1.upper_bound(u);
     51     if (it1==st1.begin()) return 0;
     52     if (it1==st1.end())     return 0;
     53 
     54     it2--;
     55     LL k = Cross((*it2)-u,(*it1)-u);
     56     if (k>=0) return 1;
     57     else return 0;
     58 }
     59 int IsInUpConvexHull(const Point &u){
     60     if (st2.count(u)>0) return 1;
     61     it2 = it1 = st2.upper_bound(u);
     62     if (it1==st2.end()) return 0;
     63     if (it1==st2.begin()) return 0;
     64     it2--;
     65     LL k = Cross((*it2)-u,(*it1)-u);
     66     if (k<=0) return 1;
     67     else return 0;
     68 }
     69 
     70 multiset<Point>:: iterator findPre(multiset<Point> &st,const Point &u){
     71     multiset<Point> :: iterator it;
     72     it = st.lower_bound(u);
     73     if (it==st.begin()) return st.end();
     74     it--;
     75     return it;
     76 
     77 }
     78 multiset<Point>:: iterator findNext(multiset<Point> &st,const Point &u){
     79     multiset<Point> :: iterator it;
     80     it = st.upper_bound(u);
     81     return it;
     82 }
     83 void Insert(const Point &u){
     84     int tmp2=IsInUpConvexHull(u),tmp1=IsInDownConvexHull(u);
     85     if (tmp1 && tmp2) return;
     86     if (tmp1==0){
     87         while (1){
     88             it1 = findNext(st1,u);
     89             if (it1==st1.end()) break;
     90             it2 = findNext(st1,*it1);
     91             if (it2==st1.end()) break;
     92             LL k = Cross((*it1)-u,(*it2)-u);
     93             if (k <= 0 ){
     94                 st1.erase(*it1);
     95             }else break;
     96         }
     97         while (1){
     98             it1 = findPre(st1,u);
     99             if (it1==st1.end()) break;
    100             it2 = findPre(st1,*it1);
    101             if (it2==st1.end()) break;
    102             LL k = Cross( (*it1)-u,(*it2)-u );
    103              if (k >= 0){
    104                 st1.erase(*it1);
    105             }else break;
    106         }
    107         st1.insert(u);
    108     }
    109     if (tmp2==0){
    110         while (1){
    111             it1 = findNext(st2,u);
    112             if (it1==st2.end()) break;
    113             it2 = findNext(st2,*it1);
    114             if (it2==st2.end() ) break;
    115             LL k = Cross((*it1)-u,(*it2)-u);
    116             if (k >= 0){
    117                 st2.erase(*it1);
    118             }else break;
    119         }
    120         while (1){
    121             it1 = findPre(st2,u);
    122             if (it1==st2.end()) break;
    123             it2 = findPre(st2,*it1);
    124             if (it2==st2.end()) break;
    125             LL k = Cross((*it1)-u,(*it2)-u);
    126             if (k <= 0){
    127                 st2.erase(*it1);
    128             }else break;
    129         }
    130         st2.insert(u);
    131     }
    132 }
    133 void solve(){
    134     init();
    135     for (int i=3;i<n;i++){
    136         int t,x,y;
    137         scanf("%d%d%d",&t,&x,&y);
    138         if (t==1){
    139             Insert(Point(x,y));
    140         }else {
    141 
    142             int t1=IsInUpConvexHull(Point(x,y));
    143             int t2=IsInDownConvexHull(Point(x,y));
    144             if ((t1 && t2)) printf("YES
    ");
    145             else printf("NO
    ");
    146         }
    147 
    148     }
    149 }
    150 int main(){
    151     freopen("in.txt","r",stdin);
    152     while (~scanf("%d",&n)){
    153         st1.clear(); st2.clear();
    154         for (int i=0;i<3;i++){
    155             int t,x,y;
    156             scanf("%d%d%d",&t,&x,&y);
    157             tp[i]=Point(x,y);                
    158         }
    159         solve();
    160     }
    161 
    162     return 0;
    163 }

    极角序:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<vector>
      8 #include<set>
      9 using namespace std;
     10 const int N=100000+10;
     11 typedef long long LL;
     12 const double eps=1e-8;
     13 double xx,yy;
     14 int dcmp(double x){
     15     return x<-eps?-1:x>eps;
     16 }
     17 LL sqr(LL x){
     18     return x*x;
     19 }
     20 struct Point{
     21     LL x,y;
     22     double angle;
     23     Point(LL a=0,LL b=0):x(a),y(b){}
     24     void ch(){
     25         angle=atan2((double)(y-yy),(double)(x-xx));
     26     }
     27     bool operator < (const Point &p)const{
     28         return dcmp(angle-p.angle)<0 || ( dcmp(angle-p.angle)==0  && sqr(x-xx)+sqr(y-yy)<sqr(p.x-xx)+sqr(p.y-yy) );
     29     }
     30     Point operator - (const Point &p)const{
     31         return Point(x-p.x,y-p.y);
     32     }
     33     bool operator ==(const Point &p) const{
     34         return x==p.x && y==p.y;
     35     }
     36     void output(){
     37         cout<< x<< " "<<y << " "<<angle <<endl;
     38     }
     39 };
     40 LL Cross(const Point &u,const Point &v){
     41     return (LL)u.x*v.y-(LL)u.y*v.x;
     42 }
     43 multiset<Point> st;
     44 multiset<Point> :: iterator it;
     45 Point p[3];
     46 int n;
     47 LL ret;
     48 Point findNext(const Point &u){
     49 
     50     it = st.upper_bound(u);
     51     if (it==st.end()){
     52         it = st.begin();
     53     }
     54     return *it;
     55 }
     56 Point findPre(const Point &u){
     57     it = st.lower_bound(u);
     58     if (it == st.begin()){
     59         it = st.end();
     60         it--;
     61     } else it--;    
     62     return *it;
     63 }
     64 LL Dot(const Point &u,const Point &v){
     65     return u.x*v.x+u.y*v.y;
     66 }
     67 bool IsPointOnSeg(const Point &u,const Point &v,const Point &w){
     68     return Cross(u-w,v-w)==0 && Dot(u-w,v-w)<=0;
     69 }
     70 bool IsPointInConvexHull(const Point &u){
     71     if (st.count(u)>0) return 1;
     72     Point t1 = findNext(u);
     73     Point t2 = findPre(u);
     74     LL k = Cross(t1-u,t2-u);
     75     if ( k<0 || IsPointOnSeg(t1,t2,u)) return 1;
     76     return 0;
     77 }
     78 void insert(const Point &u){
     79     if (IsPointInConvexHull(u)) return;
     80     while (1){
     81         Point t1 = findNext(u);
     82         Point t2 = findNext(t1);
     83         LL k = Cross(t2-u,t1-u);
     84         if ( k >= 0) {
     85         //  ret += abs(k);
     86             st.erase(t1);
     87         }else break;
     88     }
     89     while (1){
     90         Point t1 = findPre(u);
     91         Point t2 = findPre(t1);
     92         LL k = Cross(t2-u,t1-u);
     93         
     94         if ( k <=0 ){
     95             st.erase(t1);
     96         } else break;
     97 
     98     }
     99     Point t1=findPre(u);
    100     Point t2=findNext(u);
    101     LL k=Cross(t1-u,t2-u);
    102     st.insert(u);
    103 
    104 }
    105 void solve(){
    106     st.clear();
    107     for (int i=0;i<3;i++){
    108         p[i].ch();
    109         st.insert(p[i]);
    110     }
    111     for (int i=3;i<n;i++){
    112         LL t1,x,y; 
    113         cin>>t1>>x>>y;
    114         Point t=Point(x,y);
    115         t.ch();
    116         if (t1==1) {
    117             insert(t);
    118         }
    119         else if (t1==2){
    120         /*  
    121             for (it=st.begin();it!=st.end();it++){
    122                 cout<<(*it).x<<" "<<(*it).y<<" "<<(*it).angle<<endl;
    123             }
    124             cout<<"^^^ "<<xx<<" " <<yy<<endl;
    125             t.output();
    126         */  
    127             if (IsPointInConvexHull(t)) puts("YES");
    128             else puts("NO");
    129         }
    130     }
    131 
    132 }
    133 int main(){
    134   //  freopen("in.txt","r",stdin);
    135     while (~scanf("%d",&n)){
    136         xx=0; yy=0;
    137         double t[] = {0,0.49214632134, 0.2348329743213, 0.9854827427182};
    138         double sum = 0;
    139        
    140         for (int i=0;i<3;i++) {
    141             int tmp;
    142             cin>>tmp>>p[i].x>>p[i].y;
    143             xx+=p[i].x*t[i]; yy+=p[i].y*t[i];
    144             sum+=t[i];
    145         }
    146         xx/=sum; yy/=sum;
    147         solve();
    148     }
    149 
    150     return 0;
    151 }
  • 相关阅读:
    Metricbeat
    Flask安装与基本配置
    web框架
    git
    占位
    算法
    面试
    CMDB
    order by关键字排序优化
    动态主机配置协议-DHCP
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3192284.html
Copyright © 2020-2023  润新知