【题意分析】

  给你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 }
View Code