动态凸包

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

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

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

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

那刚开始的点就可以,如果重复的话,在遇到这个点就连极角都求不出了。。。还有一些其他问题,我也不知道,就是做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\n");
145             else printf("NO\n");
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 }

 

 

posted @ 2013-07-15 22:19  Rabbit_hair  阅读(1408)  评论(0编辑  收藏  举报