[SCOI2015]小凸想跑步

题目

先推一波式子,设\(p(x,y)\),那么我们尝试写出点\((x_i,y_i),(x_{i+1},y_{i+1})\)\(p(x,y)\)形成的三角形面积,就是用叉积写一波

\[2S=(x_i-x)(y_{i+1}-y)-(x_{i+1}-x)(y_i-y)\]

大力拆开式子,发现\(2S=(y_{i}-y_{i+1})x+(x_{i+1}-x_i)y+x_iy_{i+1}-x_{i+1}y_i\)

不难发现这是一个\(Ax+By+C\)的形式,肯定跟直线有点关系,我们设\(A_i=y_{i}-y_{i+1},B_i=x_{i+1}-x_i,C_i=x_iy_{i+1}-x_{i+1}y_i\)

我们需要使得\(\forall i\in[1,n]\)\(A_0x+B_0+C_0

\((A_0-A_i)x+(B_0-B_i)y+(C_0-C_i)<0\)

不难发现这样的\((x,y)\)都在一个半平面内

确切的讲当\(B_0-B_i>0\)的时候,这样的\((x,y)\)都在直线\((A_0-A_i)x+(B_0-B_i)y+(C_0-C_i)=0\)的下方;当\(B_0-B_i<0\)时,就在直线的上方

于是我们对得到的这\(n\)条限制以及凸包上原来的\(n\)条边求一个半平面交就好了,答案就是半平面交的面积除以原来凸包的面积

代码

#include
#define re register
const double eps=1e-6;
const int maxn=2e5+5;
int n,h,t,N,tot;
struct Pt{double x,y;}p[maxn];
struct Line{Pt s,t;double det;}L[maxn],q[maxn];
inline int dcmp(double a,double b) {return a+eps>b&&a-eps0;}
inline Pt sec(const Line &A,const Line &B) {
    Pt v1=A.t-A.s,v2=B.t-B.s,v3=A.s-B.s;
    double t=(v3*v2)/(v2*v1);
    return A.s+(t^v1);
}
inline int cmp(const Line &A,const Line &B) {
    return dcmp(A.det,B.det)?OnRight(A.s,B):(A.det

你可能感兴趣的:([SCOI2015]小凸想跑步)