动态凸包

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

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

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

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

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

 

 

你可能感兴趣的:(动态)