zoukankan      html  css  js  c++  java
  • 动态凸包

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

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

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

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

    那刚开始的点就可以,如果重复的话,在遇到这个点就连极角都求不出了。。。还有一些其他问题,我也不知道,就是做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 }
  • 相关阅读:
    leetcode 347. Top K Frequent Elements
    581. Shortest Unsorted Continuous Subarray
    leetcode 3. Longest Substring Without Repeating Characters
    leetcode 217. Contains Duplicate、219. Contains Duplicate II、220. Contains Duplicate、287. Find the Duplicate Number 、442. Find All Duplicates in an Array 、448. Find All Numbers Disappeared in an Array
    leetcode 461. Hamming Distance
    leetcode 19. Remove Nth Node From End of List
    leetcode 100. Same Tree、101. Symmetric Tree
    leetcode 171. Excel Sheet Column Number
    leetcode 242. Valid Anagram
    leetcode 326. Power of Three
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3192284.html
Copyright © 2011-2022 走看看