动态凸包,就是每次插入一个点,求新形成的凸包;
就是给点一个序,然后找到插入点在凸包中的前驱后后继,然后俩边分别维护;
可以用水平序,也可以用极角序,水平序因为要分别维护上下两个半凸包,而且因为是分别的维护的,不像极角序一样
可以循环,即最后一个的点的后继就是第一个点,所以极角序相对实现起来简单,但极角有一个问题就是要找一个基准点,如果点都不重复
那刚开始的点就可以,如果重复的话,在遇到这个点就连极角都求不出了。。。还有一些其他问题,我也不知道,就是做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 }