大家都很强, 可与之共勉 。
ZZ题……
# include <cmath>
# include <cstdio>
# include <algorithm>
template < class T > inline T min ( T a, T b ) { return a > b ? b : a ; }
template < class T > inline T max ( T a, T b ) { return a > b ? a : b ; }
const double eps = 1e-8 ;
const double Pi = acos ( -1 ) ;
inline int epssgn ( double x ) {
return ( x > - eps ) - ( x < eps ) ;
} // x > eps -> 1 ; x < -eps -> -1 ; x == 0 -> 0 ;
struct Vector {
double x, y ; // len ;
Vector ( ) { }
Vector ( double x, double y ) : x ( x ), y ( y ) { /*len = sqrt ( x * x + y * y ) ;*/ }
inline Vector operator + ( const Vector rhs ) const {
return Vector ( x + rhs.x, y + rhs.y ) ;
}
inline Vector operator - ( const Vector rhs ) const {
return Vector ( x - rhs.x, y - rhs.y ) ;
}
inline Vector operator * ( const double k ) const {
return Vector ( x * k, y * k ) ;
}
inline Vector operator / ( const double k ) const {
return Vector ( x / k, y / k ) ;
}
inline double operator * ( const Vector rhs ) const {
return x * rhs.x + y * rhs.y ;
} // µã»ý
inline double operator % ( const Vector rhs ) const {
return x * rhs.y - y * rhs.x ;
} //²æ»ý
} ;
struct Point {
double x, y ;
Point ( ) { }
Point ( double x, double y ) : x ( x ), y ( y ) { }
inline Vector operator - ( const Point rhs ) const {
return Vector ( x - rhs.x, y - rhs.y ) ;
}
} ;
struct Line {
double a, b, c, angle ;
Point p1, p2 ;
Line ( ) { }
Line ( Point s, Point e ) : p1 ( s ), p2 ( e ) {
a = s.y - e.y ;
b = e.x - s.x ;
c = e.y * s.x - e.x * s.y ;
angle = atan2 ( e.y - s.y, e.x - s.x ) ; // !!!
}
inline bool operator < ( const Line& rhs ) const {
return angle < rhs.angle ;
}
} ; // ax + by + c = 0 ;
inline bool Parallel ( Line l1, Line l2 ) {
return epssgn ( l1.a * l2.b - l1.b * l2.a ) == 0 ;
}
inline bool LineEqual ( Line l1, Line l2 ) {
if ( ! Parallel ( l1, l2 ) ) return 0 ;
return ( epssgn ( l1.b * l2.a - l2.b * l1.a ) == 0 ) && ( epssgn ( l1.c * l2.a - l2.c * l1.a ) == 0 ) ;
}
inline Point GetIntersect ( Line l1, Line l2 ) {
return Point ( ( l1.b * l2.c - l2.b * l1.c ) / ( l1.a * l2.b - l2.a * l1.b ), ( l2.a * l1.c - l1.a * l2.c ) / ( l1.a * l2.b - l2.a * l1.b ) ) ;
}
struct Lcmp {
inline bool operator ( ) ( const Line& l1, const Line& l2 ) {
int d = epssgn ( l1.angle - l2.angle ) ;
if ( ! d ) return ( bool ) ( epssgn ( ( l2.p1 - l1.p1 ) % ( l2.p2 - l1.p1 ) ) > 0 ) ;
return d < 0 ;
}
} ;
inline bool IntersectionOutOfHalfPlane ( Line& hpl, Line& l1, Line& l2 ) {
Point p = GetIntersect ( l1, l2 ) ;
return ( epssgn ( ( hpl.p1 - p ) % ( hpl.p2 - p ) ) < 0 ) ; // intersection is on left ;
}
# define N 100010
int HalfPlaneIntersect ( Line* l, int n, Point* p ) {
static int dq [N] ;
int top, bot ;
std :: sort ( l, l + n, Lcmp ( ) ) ;
int i, j ;
for ( i = j = 0 ; i < n ; ++ i )
if ( epssgn ( l [i].angle - l [j].angle ) > 0 ) {
l [++ j] = l [i] ;
}
n = j + 1 ;
dq [bot = 0] = 0 ;
dq [top = 1] = 1 ;
for ( i = 2 ; i < n ; ++ i ) {
while ( top > bot && IntersectionOutOfHalfPlane ( l [i], l [dq [top]],l [dq [top - 1]] ) ) -- top ;
while ( top > bot && IntersectionOutOfHalfPlane ( l [i], l [dq [bot]],l [dq [bot + 1]] ) ) ++ bot ;
dq [++ top] = i ;
}
while ( top > bot && IntersectionOutOfHalfPlane ( l [dq [bot]],l [dq [top]],l [dq [top - 1]] ) ) -- top ;
while ( top > bot && IntersectionOutOfHalfPlane ( l [dq [top]],l [dq [bot]],l [dq [bot + 1]] ) ) ++ bot ;
dq [++ top] = dq [bot] ;
int cnt = 0 ;
for ( i = bot ; i < top ; ++ i ) p [cnt ++] = GetIntersect ( l [dq [i]], l [dq [i + 1]] ) ;
return cnt ;
}
Line l [N] ;
Point p [N] ;
# undef N
int main ( ) {
int n ;
scanf ( "%d", & n ) ;
int cnt ( 0 ) ;
while ( n -- ) {
static int m ;
scanf ( "%d", & m ) ;
for ( int i = 0 ; i < m ; ++ i ) scanf ( "%lf%lf", & p [i].x, & p [i].y ) ;
for ( int i = 0 ; i < m ; ++ i ) {
l [cnt ++] = Line ( p [i], p [i + 1 >= m ? i + 1 - m : i + 1] ) ;
}
}
int pcnt = HalfPlaneIntersect ( l, cnt, p ) ;
double ans ( 0 ) ;
for ( int i = 0 ; i < pcnt ; ++ i ) {
ans += ( p [i] - p [0] ) % ( p [i + 1 >= pcnt ? i + 1 - pcnt : i + 1] - p [0] ) ;
}
return printf ( "%.3lf\n", ans / 2 ), 0 ;
}