// BEGIN CUT HERE
// END CUT HERE
#line 5 "PolygonRotation.cpp"
#include <bits/stdc++.h>
#define LL long long
const double PI = acos ( - 1.0 ) ;
const double EPS = 1e-9 ;
using namespace std;
typedef long double CT;
struct Point {
CT x, y;
Point( ) { }
Point( CT x, CT y) : x( x) , y( y) { }
Point( const Point & p) : x( p.x ) , y( p.y ) { }
Point operator + ( const Point & p) const { return Point( x+ p.x , y+ p.y ) ; }
Point operator - ( const Point & p) const { return Point( x- p.x , y- p.y ) ; }
Point operator * ( double c) const { return Point( x* c, y* c ) ; }
Point operator / ( double c) const { return Point( x/ c, y/ c ) ; }
bool operator< ( const Point & other) const {
return this- > y > other.y ;
}
} ;
CT dot( Point p, Point q) { return p.x * q.x + p.y * q.y ; }
double dist2( Point p, Point q) { return dot( p- q,p- q) ; }
CT cross( Point p, Point q) { return p.x * q.y - p.y * q.x ; }
ostream & operator<< ( ostream & os, const Point & p) {
os << "(" << p.x << "," << p.y << ")" ;
return os;
}
bool LinesParallel( Point a, Point b, Point c, Point d) {
return fabs ( cross( b- a, c- d) ) < EPS;
}
bool LinesCollinear( Point a, Point b, Point c, Point d) {
return LinesParallel( a, b, c, d)
&& fabs ( cross( a- b, a- c) ) < EPS
&& fabs ( cross( c- d, c- a) ) < EPS;
}
// determine if line segment from a to b intersects with
// line segment from c to d
bool SegmentsIntersect( Point a, Point b, Point c, Point d) {
if ( LinesCollinear( a, b, c, d) ) {
if ( dist2( a, c) < EPS || dist2( a, d) < EPS ||
dist2( b, c) < EPS || dist2( b, d) < EPS) return true ;
if ( dot( c- a, c- b) > 0 && dot( d- a, d- b) > 0 && dot( c- b, d- b) > 0 )
return false ;
return true ;
}
if ( cross( d- a, b- a) * cross( c- a, b- a) > 0 ) return false ;
if ( cross( a- c, d- c) * cross( b- c, d- c) > 0 ) return false ;
return true ;
}
bool collinear( Point a, Point b, Point c) {
return fabs ( ( a.x - c.x ) * ( b.y - a.y ) - ( a.x - b.x ) * ( c.y - a.y ) ) < EPS;
}
bool on_segment( Point a, Point b, Point x) {
if ( x.x <= max( a.x , b.x ) and x.x >= min( a.x , b.x ) and
x.y <= max( a.y , b.y ) and x.y >= min( a.y , b.y ) ) {
return collinear( a, b, x) ;
}
return false ;
}
Point ComputeLineIntersection( Point a, Point b, Point c, Point d) {
b= b- a; d= c- d; c= c- a;
if ( ! ( dot( b, b) > EPS && dot( d, d) > EPS) ) {
return Point( - 1e18 , - 1e18 ) ;
}
assert ( dot( b, b) > EPS && dot( d, d) > EPS) ;
return a + b* cross( c, d) / cross( b, d) ;
}
CT eval( Point p1, Point p2, CT Y) {
if ( fabs ( p1.y - p2.y ) < EPS) return p1.x ;
CT m = ( p1.y - p2.y ) / ( p1.x - p2.x ) ;
return ( ( Y - p1.y ) / m) + p1.x ;
}
const int OFFSET = 110 ;
bool is_sp[ 400 ] ;
CT maxim[ 400 ] ;
class PolygonRotation {
public :
CT frustum( CT h, CT R, CT r) {
return ( ( PI * h) / 3 ) * ( R* R + R* r + r* r) ;
}
double getVolume( vector < int > x, vector < int > y) {
vector< Point> l_half, r_half;
int split = 0 ;
for ( int i = 1 ; i < x.size ( ) ; i++ ) {
if ( x[ i] == 0 ) {
split = i;
break ;
}
}
vector< CT> ys;
for ( int i = 0 ; i <= split; i++ ) {
l_half.push_back ( Point( x[ i] , y[ i] ) ) ;
ys.push_back ( y[ i] ) ;
maxim[ y[ i] + OFFSET] = max( maxim[ y[ i] + OFFSET] , ( CT) x[ i] ) ;
}
r_half.push_back ( Point( x[ 0 ] , y[ 0 ] ) ) ;
for ( int i = int ( x.size ( ) ) - 1 ; i >= split; i-- ) {
r_half.push_back ( Point( - x[ i] , y[ i] ) ) ;
ys.push_back ( y[ i] ) ;
maxim[ y[ i] + OFFSET] = max( maxim[ y[ i] + OFFSET] , ( CT) - x[ i] ) ;
}
for ( int i = 1 ; i < l_half.size ( ) ; i++ ) {
for ( int j = 1 ; j < r_half.size ( ) ; j++ ) {
if ( SegmentsIntersect( l_half[ i] , l_half[ i- 1 ] , r_half[ j] , r_half[ j- 1 ] ) ) {
Point temp = ComputeLineIntersection( l_half[ i] , l_half[ i- 1 ] , r_half[ j] , r_half[ j- 1 ] ) ;
if ( temp.y > - 1e10 ) {
ys.push_back ( temp.y ) ;
}
}
}
}
sort( ys.begin ( ) , ys.end ( ) ) ;
ys.resize ( unique( ys.begin ( ) , ys.end ( ) ) - ys.begin ( ) ) ;
CT p_r = - 1e9 , p_y = - 1e9 ;
CT res = 0 ;
for ( auto & y: ys) {
CT maxim = 0 ;
for ( auto & p: l_half) {
if ( fabs ( p.y - y) < EPS) {
maxim = max( maxim, p.x ) ;
}
}
for ( auto & p: r_half) {
if ( fabs ( p.y - y) < EPS) {
maxim = max( maxim, p.x ) ;
}
}
for ( int i = 1 ; i < l_half.size ( ) ; i++ ) {
if ( l_half[ i] .y <= y && l_half[ i- 1 ] .y >= y) {
maxim = max( maxim, eval( l_half[ i] , l_half[ i- 1 ] , y) ) ;
}
}
for ( int i = 1 ; i < r_half.size ( ) ; i++ ) {
if ( r_half[ i] .y <= y && r_half[ i- 1 ] .y >= y) {
maxim = max( maxim, eval( r_half[ i] , r_half[ i- 1 ] , y) ) ;
}
}
if ( p_y > - 1e3 ) {
CT h = y - p_y;
CT R = max( p_r, maxim) ;
CT r = min( p_r, maxim) ;
res + = frustum( h, R, r) ;
}
p_y = y;
p_r = maxim;
}
return ( double ) res;
}
} ;
Ly8gQkVHSU4gQ1VUIEhFUkUKCi8vIEVORCBDVVQgSEVSRQojbGluZSA1ICJQb2x5Z29uUm90YXRpb24uY3BwIgojaW5jbHVkZSA8Yml0cy9zdGRjKysuaD4KI2RlZmluZSBMTCBsb25nIGxvbmcKCmNvbnN0IGRvdWJsZSBQSSA9IGFjb3MoLTEuMCk7CmNvbnN0IGRvdWJsZSBFUFMgPSAxZS05OwoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnR5cGVkZWYgbG9uZyBkb3VibGUgQ1Q7CnN0cnVjdCBQb2ludCB7CiAgQ1QgeCwgeTsKICBQb2ludCgpIHt9CiAgUG9pbnQoQ1QgeCwgQ1QgeSkgOiB4KHgpLCB5KHkpIHt9CiAgUG9pbnQoY29uc3QgUG9pbnQgJnApIDogeChwLngpLCB5KHAueSkgICAge30KICBQb2ludCBvcGVyYXRvciArIChjb25zdCBQb2ludCAmcCkgIGNvbnN0IHsgcmV0dXJuIFBvaW50KHgrcC54LCB5K3AueSk7IH0KICBQb2ludCBvcGVyYXRvciAtIChjb25zdCBQb2ludCAmcCkgIGNvbnN0IHsgcmV0dXJuIFBvaW50KHgtcC54LCB5LXAueSk7IH0KICBQb2ludCBvcGVyYXRvciAqIChkb3VibGUgYykgICAgIGNvbnN0IHsgcmV0dXJuIFBvaW50KHgqYywgICB5KmMgICk7IH0KICBQb2ludCBvcGVyYXRvciAvIChkb3VibGUgYykgICAgIGNvbnN0IHsgcmV0dXJuIFBvaW50KHgvYywgICB5L2MgICk7IH0KCWJvb2wgb3BlcmF0b3I8KGNvbnN0IFBvaW50ICZvdGhlcikgY29uc3QgewoJCXJldHVybiB0aGlzLT55ID4gb3RoZXIueTsKCX0KfTsKQ1QgZG90KFBvaW50IHAsIFBvaW50IHEpICAgICB7IHJldHVybiBwLngqcS54K3AueSpxLnk7IH0KZG91YmxlIGRpc3QyKFBvaW50IHAsIFBvaW50IHEpICAgeyByZXR1cm4gZG90KHAtcSxwLXEpOyB9CkNUIGNyb3NzKFBvaW50IHAsIFBvaW50IHEpICAgeyByZXR1cm4gcC54KnEueS1wLnkqcS54OyB9Cm9zdHJlYW0gJm9wZXJhdG9yPDwob3N0cmVhbSAmb3MsIGNvbnN0IFBvaW50ICZwKSB7CiAgb3MgPDwgIigiIDw8IHAueCA8PCAiLCIgPDwgcC55IDw8ICIpIjsKCXJldHVybiBvczsKfQpib29sIExpbmVzUGFyYWxsZWwoUG9pbnQgYSwgUG9pbnQgYiwgUG9pbnQgYywgUG9pbnQgZCkgewogIHJldHVybiBmYWJzKGNyb3NzKGItYSwgYy1kKSkgPCBFUFM7Cn0KYm9vbCBMaW5lc0NvbGxpbmVhcihQb2ludCBhLCBQb2ludCBiLCBQb2ludCBjLCBQb2ludCBkKSB7CiAgcmV0dXJuIExpbmVzUGFyYWxsZWwoYSwgYiwgYywgZCkKICAgICAgJiYgZmFicyhjcm9zcyhhLWIsIGEtYykpIDwgRVBTCiAgICAgICYmIGZhYnMoY3Jvc3MoYy1kLCBjLWEpKSA8IEVQUzsKfQovLyBkZXRlcm1pbmUgaWYgbGluZSBzZWdtZW50IGZyb20gYSB0byBiIGludGVyc2VjdHMgd2l0aAovLyBsaW5lIHNlZ21lbnQgZnJvbSBjIHRvIGQKYm9vbCBTZWdtZW50c0ludGVyc2VjdChQb2ludCBhLCBQb2ludCBiLCBQb2ludCBjLCBQb2ludCBkKSB7CiAgaWYgKExpbmVzQ29sbGluZWFyKGEsIGIsIGMsIGQpKSB7CiAgICBpZiAoZGlzdDIoYSwgYykgPCBFUFMgfHwgZGlzdDIoYSwgZCkgPCBFUFMgfHwKICAgICAgZGlzdDIoYiwgYykgPCBFUFMgfHwgZGlzdDIoYiwgZCkgPCBFUFMpIHJldHVybiB0cnVlOwogICAgaWYgKGRvdChjLWEsIGMtYikgPiAwICYmIGRvdChkLWEsIGQtYikgPiAwICYmIGRvdChjLWIsIGQtYikgPiAwKQogICAgICByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKGNyb3NzKGQtYSwgYi1hKSAqIGNyb3NzKGMtYSwgYi1hKSA+IDApIHJldHVybiBmYWxzZTsKICBpZiAoY3Jvc3MoYS1jLCBkLWMpICogY3Jvc3MoYi1jLCBkLWMpID4gMCkgcmV0dXJuIGZhbHNlOwogIHJldHVybiB0cnVlOwp9CmJvb2wgY29sbGluZWFyKFBvaW50IGEsIFBvaW50IGIsIFBvaW50IGMpIHsKCXJldHVybiBmYWJzKChhLnggLSBjLngpICogKGIueSAtIGEueSkgLSAoYS54IC0gYi54KSAqIChjLnkgLSBhLnkpKSA8IEVQUzsKfQpib29sIG9uX3NlZ21lbnQoUG9pbnQgYSwgUG9pbnQgYiwgUG9pbnQgeCkgewogICAgaWYoeC54IDw9IG1heChhLngsIGIueCkgYW5kIHgueCA+PSBtaW4oYS54LCBiLngpIGFuZAogICAgICAgICAgICB4LnkgPD0gbWF4KGEueSwgYi55KSBhbmQgeC55ID49IG1pbihhLnksIGIueSkpIHsKICAgICAgICByZXR1cm4gY29sbGluZWFyKGEsIGIsIHgpOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9ClBvaW50IENvbXB1dGVMaW5lSW50ZXJzZWN0aW9uKFBvaW50IGEsIFBvaW50IGIsIFBvaW50IGMsIFBvaW50IGQpIHsKICBiPWItYTsgZD1jLWQ7IGM9Yy1hOwoJaWYoISAoZG90KGIsIGIpID4gRVBTICYmIGRvdChkLCBkKSA+IEVQUykgKSB7CgkJcmV0dXJuIFBvaW50KC0xZTE4LCAtMWUxOCk7Cgl9CiAgYXNzZXJ0KGRvdChiLCBiKSA+IEVQUyAmJiBkb3QoZCwgZCkgPiBFUFMpOwogIHJldHVybiBhICsgYipjcm9zcyhjLCBkKS9jcm9zcyhiLCBkKTsKfQpDVCBldmFsKFBvaW50IHAxLCBQb2ludCBwMiwgQ1QgWSkgewoJaWYoZmFicyhwMS55IC0gcDIueSkgPCBFUFMpIHJldHVybiBwMS54OwoJQ1QgbSA9IChwMS55IC0gcDIueSkvKHAxLnggLSBwMi54KTsKCXJldHVybiAoKFkgLSBwMS55KS9tKSArIHAxLng7Cn0KCmNvbnN0IGludCBPRkZTRVQgPSAxMTA7CmJvb2wgaXNfc3BbNDAwXTsKQ1QgbWF4aW1bNDAwXTsKCmNsYXNzIFBvbHlnb25Sb3RhdGlvbiB7CnB1YmxpYzoKCUNUIGZydXN0dW0oQ1QgaCwgQ1QgUiwgQ1QgcikgewoJCXJldHVybiAoKFBJICogaCkvMykgKiAoUipSICsgUipyICsgcipyKTsKCX0KCWRvdWJsZSBnZXRWb2x1bWUodmVjdG9yIDxpbnQ+IHgsIHZlY3RvciA8aW50PiB5KSB7CgkJdmVjdG9yPFBvaW50PiBsX2hhbGYsIHJfaGFsZjsKCQlpbnQgc3BsaXQgPSAwOwoJCWZvcihpbnQgaSA9IDE7IGkgPCB4LnNpemUoKTsgaSsrKSB7CgkJCWlmKHhbaV0gPT0gMCkgewoJCQkJc3BsaXQgPSBpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJdmVjdG9yPENUPiB5czsKCQlmb3IoaW50IGkgPSAwOyBpIDw9IHNwbGl0OyBpKyspIHsKCQkJbF9oYWxmLnB1c2hfYmFjayhQb2ludCh4W2ldLCB5W2ldKSk7CgkJCXlzLnB1c2hfYmFjayh5W2ldKTsKCQkJbWF4aW1beVtpXSArIE9GRlNFVF0gPSBtYXgobWF4aW1beVtpXSArIE9GRlNFVF0sIChDVCl4W2ldKTsKCQl9CgkJcl9oYWxmLnB1c2hfYmFjayhQb2ludCh4WzBdLCB5WzBdKSk7CgkJZm9yKGludCBpID0gaW50KHguc2l6ZSgpKSAtIDE7IGkgPj0gc3BsaXQ7IGktLSkgewoJCQlyX2hhbGYucHVzaF9iYWNrKFBvaW50KC14W2ldLCB5W2ldKSk7CgkJCXlzLnB1c2hfYmFjayh5W2ldKTsKCQkJbWF4aW1beVtpXSArIE9GRlNFVF0gPSBtYXgobWF4aW1beVtpXSArIE9GRlNFVF0sIChDVCkteFtpXSk7CgkJfQoJCWZvcihpbnQgaSA9IDE7IGkgPCBsX2hhbGYuc2l6ZSgpOyBpKyspIHsKCQkJZm9yKGludCBqID0gMTsgaiA8IHJfaGFsZi5zaXplKCk7IGorKykgewoJCQkJaWYoU2VnbWVudHNJbnRlcnNlY3QobF9oYWxmW2ldLCBsX2hhbGZbaS0xXSwgcl9oYWxmW2pdLCByX2hhbGZbai0xXSkpIHsKCQkJCQlQb2ludCB0ZW1wID0gQ29tcHV0ZUxpbmVJbnRlcnNlY3Rpb24obF9oYWxmW2ldLCBsX2hhbGZbaS0xXSwgcl9oYWxmW2pdLCByX2hhbGZbai0xXSk7CgkJCQkJaWYodGVtcC55ID4gLTFlMTApIHsKCQkJCQkJeXMucHVzaF9iYWNrKHRlbXAueSk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCXNvcnQoeXMuYmVnaW4oKSwgeXMuZW5kKCkpOwoJCXlzLnJlc2l6ZSh1bmlxdWUoeXMuYmVnaW4oKSwgeXMuZW5kKCkpIC0geXMuYmVnaW4oKSk7CgkJQ1QgcF9yID0gLTFlOSwgcF95ID0gLTFlOTsKCQlDVCByZXMgPSAwOwoJCWZvcihhdXRvICZ5OiB5cykgewoJCQlDVCBtYXhpbSA9IDA7CgkJCWZvcihhdXRvICZwOiBsX2hhbGYpIHsKCQkJCWlmKGZhYnMocC55IC0geSkgPCBFUFMpIHsKCQkJCQltYXhpbSA9IG1heChtYXhpbSwgcC54KTsKCQkJCX0KCQkJfQoJCQlmb3IoYXV0byAmcDogcl9oYWxmKSB7CgkJCQlpZihmYWJzKHAueSAtIHkpIDwgRVBTKSB7CgkJCQkJbWF4aW0gPSBtYXgobWF4aW0sIHAueCk7CgkJCQl9CgkJCX0KCQkJZm9yKGludCBpID0gMTsgaSA8IGxfaGFsZi5zaXplKCk7IGkrKykgewoJCQkJaWYobF9oYWxmW2ldLnkgPD0geSAmJiBsX2hhbGZbaS0xXS55ID49IHkpIHsKCQkJCQltYXhpbSA9IG1heChtYXhpbSwgZXZhbChsX2hhbGZbaV0sIGxfaGFsZltpLTFdLCB5KSk7CgkJCQl9CgkJCX0KCQkJZm9yKGludCBpID0gMTsgaSA8IHJfaGFsZi5zaXplKCk7IGkrKykgewoJCQkJaWYocl9oYWxmW2ldLnkgPD0geSAmJiByX2hhbGZbaS0xXS55ID49IHkpIHsKCQkJCQltYXhpbSA9IG1heChtYXhpbSwgZXZhbChyX2hhbGZbaV0sIHJfaGFsZltpLTFdLCB5KSk7CgkJCQl9CgkJCX0KCQkJaWYocF95ID4gLTFlMykgewoJCQkJQ1QgaCA9IHkgLSBwX3k7CgkJCQlDVCBSID0gbWF4KHBfciwgbWF4aW0pOwoJCQkJQ1QgciA9IG1pbihwX3IsIG1heGltKTsKCQkJCXJlcyArPSBmcnVzdHVtKGgsIFIsIHIpOwoJCQl9CgkJCXBfeSA9IHk7CgkJCXBfciA9IG1heGltOwoJCX0KCQlyZXR1cm4gKGRvdWJsZSlyZXM7Cgl9Cn07Cg==