【题意分析】
给你n个上半平面,求包含这些上半平面的交的上半平面。
【解题思路】
按斜率排序,用单调栈维护一个下凸壳即可。复杂度O(nlog2n)。
【参考代码】
1 #include <cctype> 2 #include <cmath> 3 #include <cstdio> 4 #define REP(I,start,end) for(int I=(start);I<=(end);I++) 5 #define PER(I,start,end) for(int I=(start);I>=(end);I--) 6 inline int space() 7 { 8 return putchar(' '); 9 } 10 inline int enter() 11 { 12 return putchar('\n'); 13 } 14 inline bool eoln(char ptr) 15 { 16 return ptr=='\n'; 17 } 18 inline bool eof(char ptr) 19 { 20 return ptr=='\0'; 21 } 22 inline int getint() 23 { 24 char ch=getchar(); 25 for(;!isdigit(ch)&&ch!='+'&&ch!='-';ch=getchar()); 26 bool impositive=ch=='-'; 27 if(impositive) 28 ch=getchar(); 29 int result=0; 30 for(;isdigit(ch);ch=getchar()) 31 result=(result<<3)+(result<<1)+ch-'0'; 32 return impositive?-result:result; 33 } 34 template<typename integer> inline int write(integer n) 35 { 36 integer now=n; 37 bool impositive=now<0; 38 if(impositive) 39 { 40 putchar('-'); 41 now=-now; 42 } 43 char sav[20]; 44 sav[0]=now%10+'0'; 45 int result=1; 46 for(;now/=10;sav[result++]=now%10+'0'); 47 PER(i,result-1,0) 48 putchar(sav[i]); 49 return result+impositive; 50 } 51 template<typename real> inline bool fequals(real one,real another,real eps=1e-6) 52 { 53 return fabs(one-another)<eps; 54 } 55 template<typename real> inline bool funequals(real one,real another,real eps=1e-6) 56 { 57 return fabs(one-another)>=eps; 58 } 59 template<typename T=double> struct Point 60 { 61 T x,y; 62 Point() 63 { 64 x=y=0; 65 } 66 Point(T _x,T _y) 67 { 68 x=_x; 69 y=_y; 70 } 71 bool operator==(const Point<T> &another)const 72 { 73 return fequals(x,another.x)&&fequals(y,another.y); 74 } 75 bool operator!=(const Point<T> &another)const 76 { 77 return funequals(x,another.x)||funequals(y,another.y); 78 } 79 Point<T> operator+(const Point<T> &another)const 80 { 81 Point<T> result(x+another.x,y+another.y); 82 return result; 83 } 84 Point<T> operator-(const Point<T> &another)const 85 { 86 Point<T> result(x-another.x,y-another.y); 87 return result; 88 } 89 Point<T> operator*(const T &number)const 90 { 91 Point<T> result(x*number,y*number); 92 return result; 93 } 94 Point<double> operator/(const T &number)const 95 { 96 Point<double> result(double(x)/number,double(y)/number); 97 return result; 98 } 99 double theta() 100 { 101 return x>0?(y<0)*2*M_PI+atan(y/x):M_PI+atan(y/x); 102 } 103 double theta_x() 104 { 105 return !x?M_PI/2:atan(y/x); 106 } 107 double theta_y() 108 { 109 return !y?M_PI/2:atan(x/y); 110 } 111 }; 112 template<typename T> inline T dot_product(Point<T> A,Point<T> B) 113 { 114 return A.x*B.x+A.y*B.y; 115 } 116 template<typename T> inline T cross_product(Point<T> A,Point<T> B) 117 { 118 return A.x*B.y+A.y*B.x; 119 } 120 template<typename T> inline T SqrDis(Point<T> a,Point<T> b) 121 { 122 return sqr(a.x-b.x)+sqr(a.y-b.y); 123 } 124 template<typename T> inline double Euclid_distance(Point<T> a,Point<T> b) 125 { 126 return sqrt(SqrDis(a,b)); 127 } 128 template<typename T> inline T Manhattan_distance(Point<T> a,Point<T> b) 129 { 130 return fabs(a.x-b.x)+fabs(a.y-b.y); 131 } 132 template<typename T=double> struct kbLine 133 { 134 //line:y=kx+b 135 T k,b; 136 kbLine() 137 { 138 k=b=0; 139 } 140 kbLine(T _k,T _b) 141 { 142 k=_k; 143 b=_b; 144 } 145 bool operator==(const kbLine<T> &another)const 146 { 147 return fequals(k,another.k)&&fequals(b,another.b); 148 } 149 bool operator!=(const kbLine<T> &another)const 150 { 151 return funequals(k,another.k)||funequals(b,another.b); 152 } 153 bool operator<(const kbLine<T> &another)const 154 { 155 return k<another.k; 156 } 157 bool operator>(const kbLine<T> &another)const 158 { 159 return k>another.k; 160 } 161 template<typename point_type> inline bool build_line(Point<point_type> A,Point<point_type> B) 162 { 163 if(fequals(A.x,B.x)) 164 return false; 165 k=T(A.y-B.y)/(A.x-B.x); 166 b=A.y-k*A.x; 167 return true; 168 } 169 double theta_x() 170 { 171 return atan(k); 172 } 173 double theta_y() 174 { 175 return theta_x()-M_PI/2; 176 } 177 }; 178 template<typename T> bool parallel(kbLine<T> A,kbLine<T> B) 179 { 180 return A!=B&&(fequals(A.k,B.k)||A.k!=A.k&&B.k!=B.k); 181 } 182 template<typename T> Point<double> *cross(kbLine<T> A,kbLine<T> B) 183 { 184 if(A==B||parallel(A,B)) 185 return NULL; 186 double _x=double(B.b-A.b)/(A.k-B.k); 187 Point<double> *result=new Point<double>(_x,A.k*_x+A.b); 188 return result; 189 } 190 //======================================Header Template===================================== 191 #include <algorithm> 192 using namespace std; 193 int stack[500010]; 194 struct _line 195 { 196 kbLine<> _l; 197 int order; 198 bool operator<(const _line &T)const 199 { 200 return _l<T._l||parallel(_l,T._l)&&_l.b>T._l.b; 201 } 202 }lines[500010]; 203 inline bool Order(int A,int B) 204 { 205 return lines[A].order<lines[B].order; 206 } 207 int main() 208 { 209 int n=getint(); 210 REP(i,1,n) 211 { 212 lines[i].order=i; 213 scanf("%lf%lf",&lines[i]._l.k,&lines[i]._l.b); 214 } 215 sort(lines+1,lines+n+1); 216 int top=stack[1]=1,i=2; 217 while(i<=n) 218 { 219 for(;i<=n&&(lines[i]._l==lines[stack[top]]._l||parallel(lines[i]._l,lines[stack[top]]._l));i++); 220 for(;i<=n&&top>1;top--) 221 { 222 Point<double> *last=cross(lines[stack[top-1]]._l,lines[stack[top]]._l),*now=cross(lines[i]._l,lines[stack[top]]._l); 223 if(last->x<now->x) 224 break; 225 } 226 stack[++top]=i++; 227 } 228 sort(stack+1,stack+top+1,Order); 229 REP(i,1,top) 230 { 231 write(lines[stack[i]].order); 232 space(); 233 } 234 enter(); 235 return 0; 236 }
We Secure, We Contain, We Protect.