Problem:
Problem J
Cover the Polygon with Your Disk
A convex polygon is drawn on a flat paper sheet. You are trying to place a disk in your hands to cover as large area of the polygon as possible. In other words, the intersection area of the polygon and the disk should be maximized.
Input
The input consists of a single test case, formatted as follows. All input items are integers.
$n$ $r$
$x_1$ $y_1$
.
.
.
$x_n$ $y_n$
$n$ is the number of vertices of the polygon ($3 \leq n \leq 10$). $r$ is the radius of the disk ($1 \leq r \leq 100$).
$x_i$ and $y_i$ give the coordinate values of the $i$-th vertex of the polygon ($1 \leq i \leq n$). Coordinate values satisfy $0 \leq x_i \leq 100$ and $0 \leq y_i \leq 100$.
The vertices are given in counterclockwise order. As stated above, the given polygon is convex. In other words, interior angles at all of its vertices are less than 180$^{\circ}$. Note that the border of a convex polygon never crosses or touches itself.
Output
Output the largest possible intersection area of the polygon and the disk. The answer should not have an error greater than 0.0001 ($10^{-4}$).
Sample Input 1
4 4
0 0
6 0
6 6
0 6
Sample Output 1
35.759506
Sample Input 2
3 1
0 0
2 1
1 3
Sample Output 2
2.113100
Sample Input 3
3 1
0 0
100 1
99 1
Sample Output 3
0.019798
Sample Input 4
4 1
0 0
100 10
100 12
0 1
Sample Output 4
3.137569
Sample Input 5
10 10
0 0
10 0
20 1
30 3
40 6
50 10
60 15
70 21
80 28
90 36
Sample Output 5
177.728187
Sample Input 6
10 49
50 0
79 10
96 32
96 68
79 90
50 100
21 90
4 68
4 32
21 10
Sample Output 6
7181.603297

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define ll             long long
#define pl             pair <ll,ll>
#define ps             pair <string,string>
#define vi             vector <int>
#define vl             vector <ll>
#define vpi            vector <pi>
#define vpl            vector <pl>
#define f(i,a,b)       for(ll i=(a);i<(b);i++)
#define fd(i,a,b)      for(ll i=(a);i>(b);i--)
#define Max(a,b)       ((a)>(b)?(a):(b))
#define Min(a,b)       ((a)<(b)?(a):(b))
#define x              first
#define y              second
#define si(a)          scanf("%d",&a)
#define sii(a,b)       scanf("%d %d",&a,&b)
#define siii(a,b,c)    scanf("%d %d %d",&a,&b,&c)
#define sl(a)          scanf("%lld",&a)
#define sll(a,b)       scanf("%lld %lld",&a,&b)
#define slll(a,b,c)    scanf("%lld %lld %lld",&a,&b,&c)
#define sd(a)          scanf("%lf",&a)
#define sdd(a,b)       scanf("%lf %lf",&a,&b)
#define sddd(a,b,c)    scanf("%lf %lf %lf",&a,&b,&c)
#define ss(s)          scanf("%s",s)
#define pf             printf
#define pfi(n)         printf("%d\n",n)
#define pfl(n)         printf("%lld\n",n)
#define pfls(n)        printf("%lld ",n)
#define pfci(n,ans)    printf("Case %lld: %d\n",n,ans)
#define pfcl(n,ans)    printf("Case %lld: %lld\n",n,ans)
#define pfcd(n,ans)    printf("Case %lld: %lf\n",n,ans)
#define pb             push_back
#define all(v)         v.begin(),v.end()
#define mem(a,v)       memset(a,v,sizeof(a))
#define MAX 107
#define MOD 10007
#define LG  16
#define PI (acos(-1.0))
#define ppl pair<pl,ll>
#define id(i,j,n) (n*(i-1)+j)
#define IN(n) (2*(n)-1)
#define OUT(n) (2*(n))
#define ld long double

using namespace std;

typedef pair<int,int> pii;
const ld pi = 4 * atan(1);
const ld eps = 1e-8;

inline int dcmp (ld x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
inline ld getDistance (ld x, ld y) { return sqrt(x * x + y * y); }
inline ld torad(ld deg) { return deg / 180 * pi; }

struct Point {
    ld x, y;
    Point (ld x = 0, ld y = 0): x(x), y(y) {}
    void read () { cin>>x>>y; }
    bool operator == (const Point& u) const { return dcmp(x - u.x) == 0 && dcmp(y - u.y) == 0; }
    bool operator != (const Point& u) const { return !(*this == u); }
    bool operator < (const Point& u) const { return dcmp(x - u.x) < 0 || (dcmp(x-u.x)==0 && dcmp(y-u.y) < 0); }
    bool operator > (const Point& u) const { return u < *this; }
    bool operator <= (const Point& u) const { return *this < u || *this == u; }
    bool operator >= (const Point& u) const { return *this > u || *this == u; }
    Point operator + (const Point& u) { return Point(x + u.x, y + u.y); }
    Point operator - (const Point& u) { return Point(x - u.x, y - u.y); }
    Point operator * (const ld u) { return Point(x * u, y * u); }
    Point operator / (const ld u) { return Point(x / u, y / u); }
    ld operator * (const Point& u) { return x*u.y - y*u.x; }
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Circle {
    Point o;
    ld r;
    Circle () {}
    Circle (Point o, ld r = 0): o(o), r(r) {}
    void read () { o.read(); cin>>r; }
    Point point(ld rad) { return Point(o.x + cos(rad)*r, o.y + sin(rad)*r); }
    ld getArea (ld rad) { return rad * r * r / 2; }
};

ld getDistance (Point a, Point b) { ld x=a.x-b.x, y=a.y-b.y; return sqrt(x*x + y*y); }
ld getSlope (Point a,Point b) { return atan2(b.y-a.y,b.x-a.x); }
ld getDot (Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
ld getCross (Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
ld getLength (Vector a) { return sqrt(getDot(a, a)); }
ld getPLength (Vector a) { return getDot(a, a); }
ld getAngle (Vector u) { return atan2(u.y, u.x); }
ld getAngle (Vector a, Vector b) { return acos(getDot(a, b) / getLength(a) / getLength(b)); }
Vector rotate (Vector a, ld rad) { return Vector(a.x*cos(rad)-a.y*sin(rad), a.x*sin(rad)+a.y*cos(rad)); }
Vector getNormal (Vector a) { ld l = getLength(a); return Vector(-a.y/l, a.x/l); }
ld getDirArea (Point a, Point b, Point c) { return getCross(b - a, c - a) / 2; }
ld getArea (Point a, Point b, Point c) { return fabs(getCross(b - a, c - a)) / 2; }

ld getDistanceToSegment (Point p, Point a, Point b) {
    if (a == b) return getLength(p-a);
    Vector v1 = b - a, v2 = p - a, v3 = p - b;
    if (dcmp(getDot(v1, v2)) < 0) return getLength(v2);
    else if (dcmp(getDot(v1, v3)) > 0) return getLength(v3);
    else return fabs(getCross(v1, v2) / getLength(v1));
}

ld getArea (Point* p, int n) {
    ld ret = 0;
    for (int i = 0; i < n-1; i++)
        ret += (p[i]-p[0]) * (p[i+1]-p[0]);
    return ret/2;
}

int getLineCircleIntersection (Point p, Point q, Circle O, ld& t1, ld& t2, vector<Point>& sol) {
    Vector v = q - p;
    sol.clear();
    ld a = v.x, b = p.x - O.o.x, c = v.y, d = p.y - O.o.y;
    ld e = a*a+c*c, f = 2*(a*b+c*d), g = b*b+d*d-O.r*O.r;
    ld delta = f*f - 4*e*g;
    if (dcmp(delta) < 0) return 0;
    if (dcmp(delta) == 0) {
        t1 = t2 = -f / (2 * e);
        sol.push_back(p + v * t1);
        return 1;
    }

    t1 = (-f - sqrt(delta)) / (2 * e); sol.push_back(p + v * t1);
    t2 = (-f + sqrt(delta)) / (2 * e); sol.push_back(p + v * t2);
    return 2;
}

ld getPublicAreaToTriangle (Circle O, Point a, Point b) {
    if (dcmp((a-O.o)*(b-O.o)) == 0) return 0;
    int sig = 1;
    ld da = getPLength(O.o-a), db = getPLength(O.o-b);
    if (dcmp(da-db) > 0) {
        swap(da, db);
        swap(a, b);
        sig = -1;
    }

    ld t1, t2;
    vector<Point> sol;
    int n = getLineCircleIntersection(a, b, O, t1, t2, sol);

    if (dcmp(da-O.r*O.r) <= 0) {
        if (dcmp(db-O.r*O.r) <= 0)   return getDirArea(O.o, a, b) * sig;

        int k = 0;
        if (getPLength(sol[0]-b) > getPLength(sol[1]-b)) k = 1;

        ld ret = getArea(O.o, a, sol[k]) + O.getArea(getAngle(sol[k]-O.o, b-O.o));
        ld tmp = (a-O.o)*(b-O.o);
        return ret * sig * dcmp(tmp);
    }

    ld d = getDistanceToSegment(O.o, a, b);
    if (dcmp(d-O.r) >= 0) {
        ld ret = O.getArea(getAngle(a-O.o, b-O.o));
        ld tmp = (a-O.o)*(b-O.o);
        return ret * sig * dcmp(tmp);
    }


    ld k1 = O.r / getLength(a - O.o), k2 = O.r / getLength(b - O.o);
    Point p = O.o + (a - O.o) * k1, q = O.o + (b - O.o) * k2;
    ld ret1 = O.getArea(getAngle(p-O.o, q-O.o));
    ld ret2 = O.getArea(getAngle(sol[0]-O.o, sol[1]-O.o)) - getArea(O.o, sol[0], sol[1]);
    ld ret = (ret1 - ret2), tmp = (a-O.o)*(b-O.o);
    return ret * sig * dcmp(tmp);
}

ld getPublicAreaToPolygon (Circle O, Point* p, int n) {
    if (dcmp(O.r) == 0) return 0;
    ld area = 0;
    for (int i = 0; i < n; i++) {
        int u = (i + 1) % n;
        area += getPublicAreaToTriangle(O, p[i], p[u]);
    }
    return fabs(area);
}

Point getCentroid(Point* p,int n){
    Point c;
    ld scale = 6.0 * getArea(p, n);
    for (int i = 0; i < n; i++){
      int j = (i+1) % n;
      c = c + (p[i]+p[j])*(p[i].x*p[j].y - p[j].x*p[i].y);
    }
    return c / scale;
}


Point pts[MAX];

int main(){
    int n;
    while(cin>>n){
        ld r;
        cin>>r;
        f(i,0,n){
            pts[i].read();
        }
        Point O = getCentroid(pts, n);
        ld A = getPublicAreaToPolygon(Circle(O,r), pts, n);
        ld step=1000.0;
        while(step>.000000001){
            f(j,0,100){
                ld ang=(1.0*(rand()%180))/pi;
                Point T = O+Point(cos(ang),sin(ang))*step;
                ld TA = getPublicAreaToPolygon(Circle(T,r), pts, n);
                if(TA>A){
                    A=TA;
                    O=T;
                }
            }
            f(j,0,100){
                ld ang=(1.0*(rand()%180))/pi;
                Point T = O-Point(cos(ang),sin(ang))*step;
                ld TA = getPublicAreaToPolygon(Circle(T,r), pts, n);
                if(TA>A){
                    A=TA;
                    O=T;
                }
            }
            step=.995*step;
        }
        cout<<fixed<<setprecision(12)<<A<<endl;
    }
}
accuracy: 1
time_ms: 2750
memory_kb: 3952
final_rank: 10

code_snippet: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <cstring>
#include <string>
#include <list>

using namespace std;

#define CVector CPoint
typedef long long LL;
typedef unsigned long long ULL;

const LL mod=1e9+7;
const double PI=acos(-1);
const double EPS=1e-6;
const int INF=0x3f3f3f3f;
inline int readint(){int sum=0;char c=getchar();bool f=0;while(c<'0'||c>'9'){if(c=='-') f=1;c=getchar();}while(c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}if(f) return -sum;return sum;}
inline LL readLL(){LL sum=0;char c=getchar();bool f=0;while(c<'0'||c>'9'){if(c=='-') f=1;c=getchar();}while(c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}if(f) return -sum;return sum;}

/*----------------------精度控制--------------------------*/

const double eps=1e-10;
//1:>0 0:=0 -1:<0
int dcmp(double x){
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}

/*------------------点、线结构体-------------------*/

struct Point{
    double x,y;
    Point(double x,double y):x(x),y(y){}
    Point(){}
    void Read(){ scanf("%lf%lf",&x,&y); }
    void Write(){ printf("%.10f %.10f\n",x,y); }
    bool operator<(const Point &b) const{//水平序
        if(!dcmp(x-b.x)) return y<b.y;
        return x<b.x;
    }
    /*friend bool operator<(CPoint a,CPoint b){//极角排序
        double tmp=cross(Pts[0],a,b);
        if(isZero(tmp)){
            return dist(Pts[0],a)<dist(Pts[0],b);
        }
        return tmp>0;
    }*/
};
//a->b
struct Line{
    Point a,b;
    Line(Point a,Point b):a(a),b(b){}
    Line(){}
    void Read(){ a.Read(); b.Read(); }
    void Write(){ a.Write(); b.Write(); }
};

/*---------------------点、线相关----------------------*/
Point operator +(Point a,Point b){ return Point(a.x+b.x,a.y+b.y); }
Point operator -(Point a,Point b){ return Point(a.x-b.x,a.y-b.y); }
Point operator *(Point a,double k){ return Point(k*a.x,k*a.y); }
Point operator *(double k,Point a){ return Point(k*a.x,k*a.y); }
double operator *(Point a,Point b){ return a.x*b.x+a.y*b.y; }
Point operator /(Point a,double k){ return Point(a.x/k,a.y/k); }
double operator ^(Point a,Point b){ return a.x*b.y-a.y*b.x; }

double cross(Point a,Point b){ return a.x*b.y-a.y*b.x; }
//(b-a)^(c-a)
double cross(Point a,Point b,Point c){ return cross(b-a,c-a); }
double dot(Point a,Point b){ return a.x*b.x+a.y*b.y; }
//(b-a)*(c-a)
double dot(Point a,Point b,Point c){ return dot(b-a,c-a); }

double length(Point p){ return sqrt(p*p); }
//单位化
Point unit(Point p){ return 1.0/length(p)*p; }
//求p在n方向上投影长度
double project(Point p,Point n){ return p*unit(n); }
//求a,b所夹的有向面积
double area(Point a,Point b){ return a^b*0.5; }

double distPP(Point p,Point q){ return length(p-q); }
double distPL(Point p,Line l){ return fabs((p-l.a)^(p-l.b))/length(l.a-l.b); }
double distPS(Point p,Line s){
    if(dot(s.b-s.a,p-s.a)<0.0) return length(p-s.a);
    if(dot(s.a-s.b,p-s.b)<0.0) return length(p-s.b);
    return distPL(p,s);
}

//b绕a逆时针旋转alpha后得到的点
Point rotateP(Point a,Point b,double alpha){
    Point p=b-a;
    return Point(a.x+(p.x*cos(alpha)-p.y*sin(alpha)),a.y+(p.x*sin(alpha)+p.y*cos(alpha)));
}

//b绕a逆时针旋转alpha后得到的向量
Point rotateV(Point a,Point b,double alpha){
    Point p=b-a;
    return unit(Point(p.x*cos(alpha)-p.y*sin(alpha),p.x*sin(alpha)+p.y*cos(alpha)));
}

//0:online 1:left -1:right
int sideOfL(Point p,Line l){
    double res=(p-l.a)^(p-l.b);
    return dcmp(res);
}

//求过p的l的垂线
Line vertical(Point p,Line l){
    return Line(p,p+rotateV(l.b,l.a,PI/2));
}

//垂足
Point root(Point p,Line l){
    return l.a+project(p-l.a,l.b-l.a)*unit(l.b-l.a);
}

//两向量夹角
double angleVV(Point a,Point b){ return acos(project(a,b)/length(a)); }
//两直线夹角
double angleLL(Line l,Line m){
    return acos(fabs(project(l.b-l.a,m.b-m.a)/length(l.b-l.a)));
}

//判断点p是否在线段ab上
bool PointOnS(Point p,Line l){
    return !dcmp(cross(p-l.a,l.b-l.a))&&dcmp((p-l.a)*(p-l.b))<=0;
}

//求直线交点
Point getCrossLL(Line l,Line m){
    double t=cross(m.b-m.a,l.a-m.a)/cross(l.b-l.a,m.b-m.a);
    return l.a+(l.b-l.a)*t;
}

//判断线段是否相交
bool crossSS(Line l,Line m){
    return sideOfL(l.a,m)*sideOfL(l.b,m)<=0&&sideOfL(m.a,l)*sideOfL(m.b,l)<=0;
}

/*----------------------多边形相关--------------------------*/

//0:outside 1:inside 2:online
int PointInPoly(Point t,Point *Pts,int n){
    int num=0,d1,d2,k;
    Pts[n]=Pts[0];
    for(int i=0;i<n;i++){
        if(PointOnS(t,Line(Pts[i],Pts[i+1]))) return 2;
        k=dcmp(cross(Pts[i],Pts[i+1],t));
        d1=dcmp(Pts[i].y-t.y);
        d2=dcmp(Pts[i+1].y-t.y);
        if(k>0&&d1<=0&&d2>0) num++;
        if(k<0&&d2<=0&&d1>0) num--;
    }
    return num!=0;
}

//clockwise:>0 anticlockwise:<0
double PolyArea(Point *Pts,int n){
    double pa=area(Pts[n-1],Pts[0]);
    for(int i=0;i<n-1;i++) pa+=area(Pts[i],Pts[i+1]);
    return pa;
}

//求任意多边形周长，需逆时针或顺时针排列
double PolyPerimeter(Point *Pts,int n){
    double pp=distPP(Pts[n-1],Pts[0]);
    for(int i=0;i<n-1;i++) pp+=distPP(Pts[i],Pts[i+1]);
    return pp;
}

//求多边形重心坐标
Point PolyCore(Point *Pts,int n){
    double pa=PolyArea(Pts,n);
    if(!dcmp(pa)) return Point(0,0);
    Point ans=(Pts[n-1]+Pts[0])*cross(Pts[n-1],Pts[0]);
    for(int i=0;i<n-1;i++) ans=ans+(Pts[i]+Pts[i+1])*cross(Pts[i],Pts[i+1]);
    return ans/pa/6;
}

/*----------------------凸包----------------------------*/

//Graham-scan st:anticlockwise
//<=:strict <:Non-strict
int Graham(Point *Pts,Point *st,int n){
    if(n<3) return 0;
    sort(Pts,Pts+n);
    int m=0;
    for(int i=0;i<n;i++){
        while(m>1&&dcmp(cross(st[m-2],st[m-1],Pts[i]))<0) m--;
        st[m++]=Pts[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--){
        while(m>k&&dcmp(cross(st[m-2],st[m-1],Pts[i])<0)) m--;
        st[m++]=Pts[i];
    }
    return m-1;
}

//clockwise:> anticlockwise:<
double CHDiameter(Point *Pts,int n,Line &l){
    double maxd=0.0;
    if(n<=1){
        l.a=l.b=Pts[0];
        return maxd;
    }
    for(int i=0,j=1;i<n;i++){
        while(cross(Pts[i],Pts[(i+1)%n],Pts[j])
              >cross(Pts[i],Pts[(i+1)%n],Pts[(j+1)%n])){
            j=(j+1)%n;
        }
        double d=distPP(Pts[i],Pts[j]);
        if(dcmp(d-maxd)>=0){
            maxd=d;
            l.a=Pts[i];
            l.b=Pts[j];
        }
        d=distPP(Pts[(i+1)%n],Pts[(j+1)%n]);
        if(dcmp(d-maxd)>=0){
            maxd=d;
            l.a=Pts[i];
            l.b=Pts[j];
        }
    }
    return maxd;
}

/*---------------------整点多边形---------------------------*/

int gcd(int a,int b){
    return b==0?a :gcd(b,a%b);
}

//整点多边形边界整点数
int Border_Int_Point_Num(Point *Pts,int n){
    int num=gcd(abs(int(Pts[0].x-Pts[n-1].x)),abs(int(Pts[0].y-Pts[n-1].y)));;
    for(int i=0;i<n-1;i++){
        num+=gcd(abs(int(Pts[i+1].x-Pts[i].x)),abs(int(Pts[i+1].y-Pts[i].y)));
    }
    return num;
}

//整点多边形内部整点数
int Inside_Int_Point_Num(Point *Pts,int n){
    return abs(int(PolyArea(Pts,n)))+1-Border_Int_Point_Num(Pts,n)/2;
}

/*-----------------------------半平面交-------------------------------*/

//有方向的直线
//p->p+v
struct Vector{
    Point p,v;
    double ang;
    Vector(Point p,Point v):p(p),v(v){
        ang=atan2(v.y,v.x);
    }
    Vector(){}
    bool operator<(const Vector &l) const{
        return ang<l.ang;
    }
};

//判断点p是否在直线L左边
bool onLeft(Vector L,Point p){
    return cross(L.v,p-L.p)>0;
}

//得到a与b两直线的交点
Point getCrossVV(Vector a,Vector b){
    Point u=a.p-b.p;
    double t=cross(b.v,u)/cross(a.v,b.v);
    return a.p+a.v*t;
}

//所有直线左半平面的交
int HPCross(Vector *L,int n,Point *poly){
    sort(L,L+n);
    int f=0,l=0;
    Point *p=new Point[n];
    Vector *q=new Vector[n];
    q[0]=L[0];
    for(int i=1;i<n;i++){
        while(f<l&&!onLeft(L[i],p[l-1])) l--;
        while(f<l&&!onLeft(L[i],p[f])) f++;
        q[++l]=L[i];
        if(!dcmp(cross(q[l].v,q[l-1].v))){
            l--;
            if(onLeft(q[l],L[i].p)) q[l]=L[i];
        }
        if(f<l) p[l-1]=getCrossVV(q[l-1],q[l]);
    }
    while(f<l&&!onLeft(q[f],p[l-1])) l--;
    if(l-f<=1) return 0;
    p[l]=getCrossVV(q[l],q[f]);
    int m=0;
    for(int i=f;i<=l;i++) poly[m++]=p[i];
    return m;
}

#define maxn 100005
Vector l[maxn];
bool retract(Vector *L,int n,double r,Point *poly){
    for(int i=0;i<n;i++){
        Point v=rotateV(L[i].p,L[i].p+L[i].v,PI/2);
        l[i]=Vector(L[i].p+r*v,L[i].v);
    }
    int cnt=HPCross(l,n,poly);
    return cnt;
}

/*---------------------三角形相关---------------------------*/

//三角形重心
//到三顶点距离的平方和最小的点
//到三边距离之积最大的点
Point TCore(Point a,Point b,Point c){
    return (a+b+c)/3;
}

//三角形外心
Point TCircum(Point a,Point b,Point c){
    Point cp;
    double a1=b.x-a.x;
    double b1=b.y-a.y;
    double a2=c.x-a.x;
    double b2=c.y-a.y;
    double c1=(a1*a1+b1*b1)/2;
    double c2=(a2*a2+b2*b2)/2;
    double d=a1*b2-a2*b1;
    cp.x=a.x+(c1*b2-c2*b1)/d;
    cp.y=a.y+(a1*c2-a2*c1)/d;
    return cp;
}

//三角形垂心
Point TOrtho(Point a,Point b,Point c){
    return TCore(a,b,c)*3.0-TCircum(a,b,c)*2.0;
}

//三角形内心
Point TInner(Point a,Point b,Point c){
    Point cp;
    double la=distPP(b,c),lb=distPP(c,a),lc=distPP(a,b);
    cp.x=(la*a.x+lb*b.x+lc*c.x)/(la+lb+lc);
    cp.y=(la*a.y+lb*b.y+lc*c.y)/(la+lb+lc);
    return cp;
}

//求三角形面积
double TArea(Point a,Point b,Point c){
    return fabs(cross(a,b,c))/2;
}

/*-----------------------圆相关-------------------------*/

struct Circle{
    Point o; double r;
    Circle(Point o,double r):o(o),r(r){}
    Circle(){}
    void Read(){ o.Read(); scanf("%lf",&r); }
    double area(){ return PI*r*r; }
};

//求两圆面积交
double getAreaCC(Circle a,Circle b){
    double d=(a.o.x-b.o.x)*(a.o.x-b.o.x)+(a.o.y-b.o.y)*(a.o.y-b.o.y);
    if(d<=(a.r-b.r)*(a.r-b.r)){
        return min(a.r,b.r)*min(a.r,b.r)*PI;
    }else if(d>(a.r-b.r)*(a.r-b.r)&&d<(a.r+b.r)*(a.r+b.r)){
        double m1=(a.r*a.r+d-b.r*b.r)/(2*a.r*sqrt(d));
        double m2=(b.r*b.r+d-a.r*a.r)/(2*b.r*sqrt(d));
        double s1=acos(m1)*a.r*a.r;
        double s2=acos(m2)*b.r*b.r;
        double s3=sqrt(d)*a.r*sin(acos(m1));
        return s1+s2-s3;
    }
    return 0.0;
}

int getCrossCL(Circle c,Line l,Point *cl){
    int fg=dcmp(distPL(c.o,l)-c.r);
    int cnt=0;
    if(!fg){
        cl[cnt++]=root(c.o,l);
    }else if(fg==-1){
        Point rt=root(c.o,l);
        double r=sqrt(c.r*c.r-(c.o-rt)*(c.o-rt));
        cl[cnt++]=rt+r*unit(l.b-l.a);
        cl[cnt++]=rt-r*unit(l.b-l.a);
    }
    return cnt;
}
/********************************************************/
int getCrossCS(Circle c,Line s,Point *cs){
    Point tmp[2];
    int cnt=0;
    int ct=getCrossCL(c,s,tmp);
    for(int i=0;i<ct;i++){
        if(PointOnS(tmp[i],s)) cs[cnt++]=tmp[i];
    }
    return cnt;
}

double getAreaTC(Point a,Point b,Circle c){
    double atc=fabs(cross(a-c.o,b-c.o)/2);
    if(!dcmp(atc)) return 0.0;
    double la=length(a-c.o),lb=length(b-c.o);
    Point cs[4];
    if(la<c.r+EPS&&lb>c.r-EPS){
        getCrossCS(c,Line(a,b),cs);
        Point p=cs[0];
        atc+=0.5*c.r*c.r*angleVV(p-c.o,b-c.o);
        atc-=0.5*fabs(cross(p-c.o,b-c.o));
    }else if(la>c.r-EPS&&lb<c.r+EPS){
        getCrossCS(c,Line(a,b),cs);
        Point p=cs[0];
        atc+=0.5*c.r*c.r*angleVV(p-c.o,a-c.o);
        atc-=0.5*fabs(cross(p-c.o,a-c.o));
    }else if(la>c.r-EPS&&lb>c.r-EPS){
        if(distPS(c.o,Line(a,b))<c.r+EPS){
            Point rt=root(c.o,Line(a,b));
            atc=fabs(getAreaTC(a,rt,c))+fabs(getAreaTC(rt,b,c));
        }else atc=0.5*c.r*c.r*angleVV(a-c.o,b-c.o);
    }
    if(dcmp(cross(a-c.o,b-c.o))==1) atc=-atc;
    return atc;
}

double getAreaPC(Point *Pts,int n,Circle c){
    double apc=getAreaTC(Pts[n-1],Pts[0],c);
    for(int i=0;i<n-1;i++) apc+=getAreaTC(Pts[i],Pts[i+1],c);
    return fabs(apc);
}

/********************************************************/


/*----------------------三维点、线基本函数-----------------------------*/

struct Point3{
    double x,y,z;
    Point3(double x,double y,double z):x(x),y(y),z(z){}
    Point3(){}
    void Read(){ scanf("%lf%lf%lf",&x,&y,&z); }
};

struct Line3{
    Point3 a,b;
    Line3(Point3 a,Point3 b):a(a),b(b){}
    Line3(){}
    void Read(){ a.Read(); b.Read(); }
};
Point3 operator +(Point3 a,Point3 b){ return Point3(a.x+b.x,a.y+b.y,a.z+b.z); }
Point3 operator -(Point3 a,Point3 b){ return Point3(a.x-b.x,a.y-b.y,a.z-b.z); }
double operator *(Point3 a,Point3 b){ return a.x*b.x+a.y*b.y+a.z*b.z; }
Point3 operator *(Point3 a,double k){ return Point3(a.x*k,a.y*k,a.z*k); }
Point3 operator *(double k,Point3 a){ return Point3(a.x*k,a.y*k,a.z*k); }
Point3 operator /(Point3 a,double k){ return Point3(a.x/k,a.y/k,a.z/k); }

double length(Point3 a){ return sqrt(a.x*a.x+a.y*a.y+a.z*a.z); }
Point3 unit(Point3 a){ return a/length(a); }
double dot(Point3 a,Point3 b){ return a.x*b.x+a.y*b.y+a.z*b.z; }
Point3 cross(Point3 a,Point3 b){
    return Point3(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
}
//混合积
double Mix(Point3 a,Point3 b,Point3 c){
    return dot(a,cross(b,c));
}

//两点距离
double dist(const Point3 &a,const Point3 &b){ return length(a-b); }

/*---------------------------------体积-------------------------------------*/

//四面体体积
double volume(double l,double n,double a,double m,double b,double c){
    double x,y;
    x=4*a*a*b*b*c*c-a*a*(b*b+c*c-m*m)*(b*b+c*c-m*m)-b*b*(c*c+a*a-n*n)*(c*c+a*a-n*n);
    y=c*c*(a*a+b*b-l*l)*(a*a+b*b-l*l)-(a*a+b*b-l*l)*(b*b+c*c-m*m)*(c*c+a*a-n*n);
    return sqrt(x-y)/12;
}

double volume(Point3 a,Point3 b,Point3 c,Point3 d){
    return fabs(Mix(b-a,c-a,d-a)/6);
}

#define MAXN 15
Point Pts[MAXN];
int n;
double R,minx,miny,maxx,maxy;

double sanfeny(double x){
    double l=maxy,r=miny;
    Line s=Line(Point(x,0),Point(x,1));
    for(int i=0;i<n;i++){
        Point st=getCrossLL(s,Line(Pts[i],Pts[i+1]));
        if(PointOnS(st,Line(Pts[i],Pts[i+1]))){
            l=min(l,st.y);
            r=max(r,st.y);
        }
    }
    double m1,m2;
    for(int i=0;i<100;i++){
        m1=(l+l+r)/3;
        m2=(l+r+r)/3;
        if(getAreaPC(Pts,n,Circle(Point(x,m1),R))<getAreaPC(Pts,n,Circle(Point(x,m2),R))){
            l=m1;
        }else{
            r=m2;
        }
    }
    return getAreaPC(Pts,n,Circle(Point(x,l),R));
}

double sanfenx(){
    double l=minx,r=maxx;
    double m1,m2;
    for(int i=0;i<100;i++){
        m1=(l+l+r)/3;
        m2=(l+r+r)/3;
        if(sanfeny(m1)<sanfeny(m2)){
            l=m1;
        }else{
            r=m2;
        }
    }
    return sanfeny(l);
}

int main(){ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n>>R;
    for(int i=1;i<=n;i++){
        cin>>Pts[n-i].x>>Pts[n-i].y;
        minx=min(minx,Pts[n-i].x);
        miny=min(miny,Pts[n-i].y);
        maxx=max(maxx,Pts[n-i].x);
        maxy=max(maxy,Pts[n-i].y);
    }
    Pts[n]=Pts[0];
    double maans=sanfenx();
    cout.setf(ios::fixed);
    cout<<fixed<<setprecision(10)<<maans<<endl;
    return 0;
}

//cout.setf(ios::fixed);
//cout<<fixed<<setprecision(10)<<s<<endl;
accuracy: 0.07407407407407407
time_ms: 40
memory_kb: 4080
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define ll             long long
#define pl             pair <ll,ll>
#define ps             pair <string,string>
#define vi             vector <int>
#define vl             vector <ll>
#define vpi            vector <pi>
#define vpl            vector <pl>
#define f(i,a,b)       for(ll i=(a);i<(b);i++)
#define fd(i,a,b)      for(ll i=(a);i>(b);i--)
#define Max(a,b)       ((a)>(b)?(a):(b))
#define Min(a,b)       ((a)<(b)?(a):(b))
#define x              first
#define y              second
#define si(a)          scanf("%d",&a)
#define sii(a,b)       scanf("%d %d",&a,&b)
#define siii(a,b,c)    scanf("%d %d %d",&a,&b,&c)
#define sl(a)          scanf("%lld",&a)
#define sll(a,b)       scanf("%lld %lld",&a,&b)
#define slll(a,b,c)    scanf("%lld %lld %lld",&a,&b,&c)
#define sd(a)          scanf("%lf",&a)
#define sdd(a,b)       scanf("%lf %lf",&a,&b)
#define sddd(a,b,c)    scanf("%lf %lf %lf",&a,&b,&c)
#define ss(s)          scanf("%s",s)
#define pf             printf
#define pfi(n)         printf("%d\n",n)
#define pfl(n)         printf("%lld\n",n)
#define pfls(n)        printf("%lld ",n)
#define pfci(n,ans)    printf("Case %lld: %d\n",n,ans)
#define pfcl(n,ans)    printf("Case %lld: %lld\n",n,ans)
#define pfcd(n,ans)    printf("Case %lld: %lf\n",n,ans)
#define pb             push_back
#define all(v)         v.begin(),v.end()
#define mem(a,v)       memset(a,v,sizeof(a))
#define MAX 107
#define MOD 10007
#define LG  16
#define PI (acos(-1.0))
#define ppl pair<pl,ll>
#define id(i,j,n) (n*(i-1)+j)
#define IN(n) (2*(n)-1)
#define OUT(n) (2*(n))
#define ld long double

using namespace std;

typedef pair<int,int> pii;
const ld pi = 4 * atan(1);
const ld eps = 1e-8;

inline int dcmp (ld x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
inline ld getDistance (ld x, ld y) { return sqrt(x * x + y * y); }
inline ld torad(ld deg) { return deg / 180 * pi; }

struct Point {
    ld x, y;
    Point (ld x = 0, ld y = 0): x(x), y(y) {}
    void read () { cin>>x>>y; }
    bool operator == (const Point& u) const { return dcmp(x - u.x) == 0 && dcmp(y - u.y) == 0; }
    bool operator != (const Point& u) const { return !(*this == u); }
    bool operator < (const Point& u) const { return dcmp(x - u.x) < 0 || (dcmp(x-u.x)==0 && dcmp(y-u.y) < 0); }
    bool operator > (const Point& u) const { return u < *this; }
    bool operator <= (const Point& u) const { return *this < u || *this == u; }
    bool operator >= (const Point& u) const { return *this > u || *this == u; }
    Point operator + (const Point& u) { return Point(x + u.x, y + u.y); }
    Point operator - (const Point& u) { return Point(x - u.x, y - u.y); }
    Point operator * (const ld u) { return Point(x * u, y * u); }
    Point operator / (const ld u) { return Point(x / u, y / u); }
    ld operator * (const Point& u) { return x*u.y - y*u.x; }
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Circle {
    Point o;
    ld r;
    Circle () {}
    Circle (Point o, ld r = 0): o(o), r(r) {}
    void read () { o.read(); cin>>r; }
    Point point(ld rad) { return Point(o.x + cos(rad)*r, o.y + sin(rad)*r); }
    ld getArea (ld rad) { return rad * r * r / 2; }
};

ld getDistance (Point a, Point b) { ld x=a.x-b.x, y=a.y-b.y; return sqrt(x*x + y*y); }
ld getSlope (Point a,Point b) { return atan2(b.y-a.y,b.x-a.x); }
ld getDot (Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
ld getCross (Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
ld getLength (Vector a) { return sqrt(getDot(a, a)); }
ld getPLength (Vector a) { return getDot(a, a); }
ld getAngle (Vector u) { return atan2(u.y, u.x); }
ld getAngle (Vector a, Vector b) { return acos(getDot(a, b) / getLength(a) / getLength(b)); }
Vector rotate (Vector a, ld rad) { return Vector(a.x*cos(rad)-a.y*sin(rad), a.x*sin(rad)+a.y*cos(rad)); }
Vector getNormal (Vector a) { ld l = getLength(a); return Vector(-a.y/l, a.x/l); }
ld getDirArea (Point a, Point b, Point c) { return getCross(b - a, c - a) / 2; }
ld getArea (Point a, Point b, Point c) { return fabs(getCross(b - a, c - a)) / 2; }

ld getDistanceToSegment (Point p, Point a, Point b) {
    if (a == b) return getLength(p-a);
    Vector v1 = b - a, v2 = p - a, v3 = p - b;
    if (dcmp(getDot(v1, v2)) < 0) return getLength(v2);
    else if (dcmp(getDot(v1, v3)) > 0) return getLength(v3);
    else return fabs(getCross(v1, v2) / getLength(v1));
}

ld getArea (Point* p, int n) {
    ld ret = 0;
    for (int i = 0; i < n-1; i++)
        ret += (p[i]-p[0]) * (p[i+1]-p[0]);
    return ret/2;
}

int getLineCircleIntersection (Point p, Point q, Circle O, ld& t1, ld& t2, vector<Point>& sol) {
    Vector v = q - p;
    sol.clear();
    ld a = v.x, b = p.x - O.o.x, c = v.y, d = p.y - O.o.y;
    ld e = a*a+c*c, f = 2*(a*b+c*d), g = b*b+d*d-O.r*O.r;
    ld delta = f*f - 4*e*g;
    if (dcmp(delta) < 0) return 0;
    if (dcmp(delta) == 0) {
        t1 = t2 = -f / (2 * e);
        sol.push_back(p + v * t1);
        return 1;
    }

    t1 = (-f - sqrt(delta)) / (2 * e); sol.push_back(p + v * t1);
    t2 = (-f + sqrt(delta)) / (2 * e); sol.push_back(p + v * t2);
    return 2;
}

ld getPublicAreaToTriangle (Circle O, Point a, Point b) {
    if (dcmp((a-O.o)*(b-O.o)) == 0) return 0;
    int sig = 1;
    ld da = getPLength(O.o-a), db = getPLength(O.o-b);
    if (dcmp(da-db) > 0) {
        swap(da, db);
        swap(a, b);
        sig = -1;
    }

    ld t1, t2;
    vector<Point> sol;
    int n = getLineCircleIntersection(a, b, O, t1, t2, sol);

    if (dcmp(da-O.r*O.r) <= 0) {
        if (dcmp(db-O.r*O.r) <= 0)   return getDirArea(O.o, a, b) * sig;

        int k = 0;
        if (getPLength(sol[0]-b) > getPLength(sol[1]-b)) k = 1;

        ld ret = getArea(O.o, a, sol[k]) + O.getArea(getAngle(sol[k]-O.o, b-O.o));
        ld tmp = (a-O.o)*(b-O.o);
        return ret * sig * dcmp(tmp);
    }

    ld d = getDistanceToSegment(O.o, a, b);
    if (dcmp(d-O.r) >= 0) {
        ld ret = O.getArea(getAngle(a-O.o, b-O.o));
        ld tmp = (a-O.o)*(b-O.o);
        return ret * sig * dcmp(tmp);
    }


    ld k1 = O.r / getLength(a - O.o), k2 = O.r / getLength(b - O.o);
    Point p = O.o + (a - O.o) * k1, q = O.o + (b - O.o) * k2;
    ld ret1 = O.getArea(getAngle(p-O.o, q-O.o));
    ld ret2 = O.getArea(getAngle(sol[0]-O.o, sol[1]-O.o)) - getArea(O.o, sol[0], sol[1]);
    ld ret = (ret1 - ret2), tmp = (a-O.o)*(b-O.o);
    return ret * sig * dcmp(tmp);
}

ld getPublicAreaToPolygon (Circle O, Point* p, int n) {
    if (dcmp(O.r) == 0) return 0;
    ld area = 0;
    for (int i = 0; i < n; i++) {
        int u = (i + 1) % n;
        area += getPublicAreaToTriangle(O, p[i], p[u]);
    }
    return fabs(area);
}

Point getCentroid(Point* p,int n){
    Point c;
    ld scale = 6.0 * getArea(p, n);
    for (int i = 0; i < n; i++){
      int j = (i+1) % n;
      c = c + (p[i]+p[j])*(p[i].x*p[j].y - p[j].x*p[i].y);
    }
    return c / scale;
}


Point pts[MAX];

int main(){
    int n;
    while(cin>>n){
        ld r;
        cin>>r;
        f(i,0,n){
            pts[i].read();
        }
        Point O = getCentroid(pts, n);
        ld A = getPublicAreaToPolygon(Circle(O,r), pts, n);
        ld step=200.0;
        while(step>.0000001){
            f(j,0,10){
                ld ang=(1.0*(rand()%180))/pi;
                Point T = O+Point(cos(ang),sin(ang))*step;
                ld TA = getPublicAreaToPolygon(Circle(T,r), pts, n);
                if(TA>A){
                    A=TA;
                    O=T;
                }
            }
            f(j,0,10){
                ld ang=(1.0*(rand()%180))/pi;
                Point T = O-Point(cos(ang),sin(ang))*step;
                ld TA = getPublicAreaToPolygon(Circle(T,r), pts, n);
                if(TA>A){
                    A=TA;
                    O=T;
                }
            }
            step=.9*step;
        }
        cout<<fixed<<setprecision(8)<<A<<endl;
    }
}
accuracy: 0.9629629629629629
time_ms: 10
memory_kb: 3948
final_rank: 11

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

using mP = pair<modint, modint>;
//-----------------------------------

typedef complex<ld> Point;
ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
namespace std {
	bool operator<(const Point& lhs, const Point& rhs) {
		return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
	}
}
struct Line {
	Point a, b;
};
struct Circle {
	Point p; ld r;
};
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//counter clockwise
	if (cross(b, c) < -eps)return -1;//clock wise
	if (dot(b, c) < 0)return 2;//c--a--b on line
	if (norm(b) < norm(c))return -2;//a--b--c on line
	return 0; //a--c--b on line
}
bool eq(ld a, ld b) {
	return abs(a - b) < eps;
}
//2直線の交差判定
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
//直線と線分の交差判定
bool isis_ls(Line l, Line s) {
	return (cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}
//点が直線上に存在するか
bool isis_lp(Line l, Point p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}
//点が線分上に存在するか
bool isis_sp(Line s, Point p) {
	//誤差がisis_lpに比べて大きいので、できるだけisis_lpを使う
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
//線分と線分の交差判定
//bool isis_ss(Line s, Line t) {
//	return(cross(s.b - s.a, t.a - s.a)*cross(s.b - s.a, t.b - s.a) < -eps && cross(t.b - t.a, s.a - t.a)*cross(t.b - t.a, s.b - t.a) < -eps);
//}
//線分と線分の交差判定2
bool isis_ss(Line s, Line t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
//直線と直線の交点
//平行な２直線に対しては使うな！！！！
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
//直線と点の距離
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}
//直線と直線の距離
ld dist_ll(Line l, Line m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}
//線分と直線の距離
ld dist_ls(Line l, Line s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}
//線分と点の距離
ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
//線分と線分の距離
ld dist_ss(Line s, Line t) {
	if (isis_ss(s, t))return 0;
	return min({ dist_sp(s,t.a),dist_sp(s,t.b),dist_sp(t,s.a),dist_sp(t,s.b) });
}
//線分と線分の交点、平行な場合は端点両方
vector<Point> is_ss(Line s1, Line s2) {
	if (!isis_ss(s1, s2))return {};
	vector<Point> res;
	if (abs(cross(s1.b - s1.a, s2.b - s2.a)) < eps) {
		if (isis_sp(s1, s2.a)) res.push_back(s2.a);
		if (isis_sp(s1, s2.b)) res.push_back(s2.b);
		if (isis_sp(s2, s1.a)) res.push_back(s1.a);
		if (isis_sp(s2, s1.b)) res.push_back(s1.b);
	}
	else {
		res.push_back(is_ll(s1, s2));
	}
	return res;
}

//円と直線の交点
//やっぱり交点が無かったらnullを返される
//交点は大体いつも2つあるのでvector
vector<Point> is_lc(Circle c, Line l) {
	vector<Point> res;
	ld d = dist_lp(l, c.p);
	if (d > c.r + eps)return res;
	ld len = (d > c.r) ? 0.0 : sqrt(c.r * c.r - d * d);
	Point nor = (l.a - l.b) / abs(l.a - l.b);
	res.push_back(proj(l, c.p) + len * nor);
	res.push_back(proj(l, c.p) - len * nor);
	return res;
}
//円と線分の交点
//2つあるかもね
//無かったらnull
vector<Point> is_sc(Circle c, Line s) {
	vector<Point> res, cop; cop = is_lc(c, s);
	int len = cop.size();
	rep(k, len) {
		if (ccw(s.a, cop[k], s.b) == -2) {
			res.push_back(cop[k]);
		}
	}
	return res;
}
using polygon = vector<Point>;
//0 -> on polygon, 1-> in polygon, 2-> out polygon
int is_in_polygon(polygon& poly, Point p) {
	ld sum = 0;
	int n = poly.size();
	rep(i, n) {
		int ni = i + 1 == n ? 0 : i + 1;
		Point pl = poly[i];
		Point pr = poly[ni];
		Line e = { pl,pr };
		if (isis_sp(e, p))return 0;
		sum += arg((pr - p) / (pl - p));
	}
	if (abs(sum) < pi / 2)return 2;
	return 1;
}

void solve() {
	int n; cin >> n; int r; cin >> r;
	vector<int> x(n), y(n);
	rep(i, n)cin >> x[i] >> y[i];
	polygon p(n);
	rep(i, n)p[i] = { (ld)x[i],(ld)y[i] };
	auto calc = [&](Point x) {
		Circle c = { x,(ld)r };
		vector<Point> cs;
		rep(i, n) {
			cs.push_back(p[i]);
			int ni = i + 1 == n ? 0 : i + 1;
			Line l = { p[i],p[ni] };
			auto cp = is_sc(c, l);
			for (auto p : cp)cs.push_back(p);
		}
		vector<pair<ld, int>> vp;
		rep(i, cs.size()) {
			//if (abs(cs[i] - x) < eps)continue;
			vp.push_back({ arg(cs[i] - x),i });
		}
		sort(all(vp));
		ld res = 0;
		rep(i, vp.size()) {
			int ni = i + 1 == vp.size() ? 0 : i + 1;
			Point mid = cs[vp[i].second] + cs[vp[ni].second];
			mid /= 2;
			if (abs(mid - x) <= r) {
				//cout << "wow " << cs[vp[i].second] << " " << cs[vp[ni].second] << "\n";
				res += abs(cross(cs[vp[i].second] - x, cs[vp[ni].second]-x))/2;
			}
			else {
				//cout << "hello\n";
				ld t = vp[ni].first - vp[i].first; if (t < 0)t += 2 * pi;
				res += t * r*r/2;
			}
		}
		return res;
	};
	auto calcy = [&](ld y) {
		Line l = { {-1,y},{101,y} };
		ld lx = 101, rx = -1;
		rep(i, n) {
			int ni = i + 1 == n? 0: i + 1;
			auto vs = is_ss(l, { p[i],p[ni] });
			for (auto p : vs) {
				chmin(lx, real(p));
				chmax(rx, real(p));
			}
		}
		rep(aa, 50) {
			ld m1 = (2 * lx + rx) / 3;
			ld m2 = (lx + 2 * rx) / 3;
			ld c1 = calc({ m1,y });
			ld c2 = calc({ m2,y });
			if (c1 > c2) {
				rx = m2;
			}
			else {
				lx = m1;
			}
		}
		return calc({ lx,y });
	};
	ld ly = 101, ry = -1;
	rep(i, n) {
		chmin(ly, imag(p[i]));
		chmax(ry, imag(p[i]));
	}
	rep(aa, 50) {
		ld m1 = (2 * ly + ry) / 3;
		ld m2 = (ly + 2 * ry) / 3;
		ld c1 = calcy(m1);
		ld c2 = calcy(m2);
		if (c1 > c2) {
			ry = m2;
		}
		else {
			ly = m1;
		}
	}
	cout << calcy(ly) << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//while(true)
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 11868
final_rank: 9

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;




struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Circle{
	Point center;
	double r;
};

struct Line{
	Point p[2];
	Line(Point p1,Point p2){
		p[0] = p1;
		p[1] = p2;
	}
	Line(){

	}
};

int N;
double r;
double min_x,max_x,min_y,max_y;
bool is_out[15];
Polygon POLYGON;


double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

Point project(Line l,Point p){

	Vector base = l.p[1]-l.p[0];
	double r = dot(p-l.p[0],base)/norm(base);
	return l.p[0]+base*r;
}

//円と直線の交点を求める関数
vector<Point> getCrossPoints(Circle c,Line l){

	vector<Point> ret;

	Vector pr = project(l,c.center);
	Vector e = (l.p[1]-l.p[0])/abs(l.p[1]-l.p[0]);

	double base;

	if(fabs(c.r*c.r-norm(pr-c.center)) < EPS){

		base = 0;
	}else{
		base = sqrt(c.r*c.r-norm(pr-c.center));
	}

	ret.push_back(Point(pr+e*base));
	ret.push_back(Point(pr-e*base));

	return ret;
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[0].y-A.p[1].y)/(A.p[0].x-A.p[1].x);
	}
}

//★★線分ではなく直線と点の距離★★
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//★★点と線分の距離★★
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

double calc_S(Polygon g){

	int N = g.size();
	double ret = 0;

	for(int i = 0; i < g.size(); i++){
		ret += cross(g[i],g[(i+1)%N]);
	}
	return ret/2.0;
}

double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(x1 != x2){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}


//円とポリゴンの共通面積を求める
double calc_common_S(Circle circle,Polygon polygon){

	//それぞれの頂点が、円の内部にあるか否かを調べる
	for(int i = 0; i < N; i++){

		double tmp_dist = calc_dist(polygon[i],circle.center);

		if(tmp_dist <= circle.r){

			is_out[i] = false; //中

		}else{

			is_out[i] = true; //外
		}
	}

	double ret = 0;

	for(int i = 0; i < N; i++){

		Point left = polygon[i];
		Point right = polygon[(i+1)%N];

		Line tmp_line = Line(left,right);
		double tmp_dist = getDistanceSP(tmp_line,circle.center);

		if(is_out[i] == false && is_out[(i+1)%N] == false){ //両方中

			Polygon tmp;
			tmp.push_back(circle.center);
			tmp.push_back(right);
			tmp.push_back(left);


			ret += calc_S(tmp);

		}else if(is_out[i] == true && is_out[(i+1)%N] == true){ //両方外

			//printf("点%dと点%dは両方外\n",i,(i+1)%N);

			if(tmp_dist > circle.r){ //両方外かつ交点なし:扇形

				Vector vec1 = left-circle.center;
				Vector vec2 = right-circle.center;

				double theta = acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));

				ret += (r*r*theta)/2;

			}else{ //交点あり

				vector<Point> cross_points = getCrossPoints(circle,Line(left,right));
				if(calc_dist(left,cross_points[1]) < calc_dist(left,cross_points[0])){

					swap(cross_points[0],cross_points[1]);
				}

				//左側扇形
				Vector vec1 = left-circle.center;
				Vector vec2 = cross_points[0]-circle.center;

				double theta = acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));

				ret += (r*r*theta)/2;

				//三角形
				Polygon tmp;
				tmp.push_back(circle.center);
				tmp.push_back(cross_points[1]);
				tmp.push_back(cross_points[0]);

				ret += calc_S(tmp);

				//右側扇形
				Vector vec3 = cross_points[1]-circle.center;
				Vector vec4 = right-circle.center;

				double theta2 = acos(dot(vec3,vec4)/(abs(vec3)*abs(vec4)));

				ret += (r*r*theta2)/2;
			}

		}else{

			if(is_out[i] == true){ //leftが外

				vector<Point> cross_points = getCrossPoints(circle,Line(left,right));

				//leftに近い方が交点
				Point cross_point;
				if(calc_dist(left,cross_points[0]) < calc_dist(left,cross_points[1])){

					cross_point = cross_points[0];

				}else{

					cross_point = cross_points[1];
				}

				//左扇
				Vector vec1 = left-circle.center;
				Vector vec2 = cross_point-circle.center;

				double theta = acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));

				ret += (r*r*theta)/2;

				//三角形
				Polygon tmp;
				tmp.push_back(circle.center);
				tmp.push_back(right);
				tmp.push_back(cross_point);

				ret += calc_S(tmp);

			}else{ //rightが外

				vector<Point> cross_points = getCrossPoints(circle,Line(left,right));

				//rightに近い方が交点
				Point cross_point;
				if(calc_dist(right,cross_points[0]) < calc_dist(right,cross_points[1])){

					cross_point = cross_points[0];

				}else{

					cross_point = cross_points[1];
				}

				//三角形
				Polygon tmp;
				tmp.push_back(circle.center);
				tmp.push_back(cross_point);
				tmp.push_back(left);

				ret += calc_S(tmp);

				//右扇
				Vector vec1 = cross_point-circle.center;
				Vector vec2 = right-circle.center;

				double theta = acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));

				ret += (r*r*theta)/2;
			}
		}
	}

	return ret;
}


int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

double thirds_searchY(double X){

	double L = max_y,R = min_y;

	//交点を持つy座標の範囲を求める
	Line line = Line(Point(X,-1000),Point(X,1000));

	bool FLG = false;

	for(int i = 0; i < N; i++){

		Line tmp = Line(POLYGON[i],POLYGON[(i+1)%N]);

		if(is_Cross(line,tmp)){

			Point p = calc_Cross_Point(tmp,line);
			L = min(L,p.y);
			R = max(R,p.y);

			FLG = true;
		}
	}

	if(!FLG)return 0;


	for(int loop = 0; loop < 100; loop++){

		double mid1 = (2.0*L+R)/3.0;
		double mid2 = (1.0*L+2.0*R)/3.0;

		Circle circle1,circle2;

		circle1.center.x = X;
		circle1.center.y = mid1;
		circle1.r = r;

		circle2.center.x = X;
		circle2.center.y = mid2;
		circle2.r = r;

		if(calc_common_S(circle1,POLYGON) > calc_common_S(circle2,POLYGON)){

			R = mid2;
		}else{

			L = mid1;
		}
	}

	Circle circle;
	circle.center.x = X;
	circle.center.y = (L+R)/2;
	circle.r = r;

	return calc_common_S(circle,POLYGON);
}

double thirds_searchX(){

	double L = min_x,R = max_x;

	for(int loop = 0; loop < 100; loop++){

		double mid1 = (2.0*L+R)/3.0;
		double mid2 = (1.0*L+2.0*R)/3.0;

		if(thirds_searchY(mid1) > thirds_searchY(mid2)){

			R = mid2;
		}else{

			L = mid1;
		}
	}

	return thirds_searchY((L+R)/2);
}


int main(){

	scanf("%d %lf",&N,&r);

	min_x = BIG_NUM;
	min_y = BIG_NUM;

	max_x = -BIG_NUM;
	max_y = -BIG_NUM;

	for(int i = 0; i < N; i++){

		double x,y;
		scanf("%lf %lf",&x,&y);

		min_x = min(min_x,x);
		min_y = min(min_y,y);

		max_x = max(max_x,x);
		max_y = max(max_y,y);

		POLYGON.push_back(Point(x,y));
	}

	reverse(POLYGON.begin(),POLYGON.end());

	printf("%.10lf\n",thirds_searchX());

	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3636
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}



#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define PI 3.141592653589793238
 
// COUNTER CLOCKWISE
static const int CCW_COUNTER_CLOCKWISE = 1;
static const int CCW_CLOCKWISE = -1;
static const int CCW_ONLINE_BACK = 2;
static const int CCW_ONLINE_FRONT = -2;
static const int CCW_ON_SEGMENT = 0;

//Intercsect Circle & Circle
static const int ICC_SEPERATE = 4;
static const int ICC_CIRCUMSCRIBE = 3;
static const int ICC_INTERSECT = 2;
static const int ICC_INSCRIBE = 1;
static const int ICC_CONTAIN = 0;

struct Point{
  double x,y;
  Point(){}
  Point(double x,double y) :x(x),y(y){}
  Point operator+(Point p) {return Point(x+p.x,y+p.y);}
  Point operator-(Point p) {return Point(x-p.x,y-p.y);}
  Point operator*(double k){return Point(x*k,y*k);}
  Point operator/(double k){return Point(x/k,y/k);}
  double norm(){return x*x+y*y;}
  double abs(){return sqrt(norm());}

  bool operator < (const Point &p) const{
    return x!=p.x?x<p.x:y<p.y;
    //grid-point only
    //return !equals(x,p.x)?x<p.x:!equals(y,p.y)?y<p.y:0;
  }

  bool operator == (const Point &p) const{
    return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
  }
};

struct EndPoint{
  Point p;
  int seg,st;
  EndPoint(){}
  EndPoint(Point p,int seg,int st):p(p),seg(seg),st(st){}
  bool operator<(const EndPoint &ep)const{
    if(p.y==ep.p.y) return st<ep.st;
    return p.y<ep.p.y;
  }
};

istream &operator >> (istream &is,Point &p){
  is>>p.x>>p.y;
  return is;
}

ostream &operator << (ostream &os,Point p){
  os<<fixed<<setprecision(12)<<p.x<<" "<<p.y;
  return os;
}

bool sort_x(Point a,Point b){
  return a.x!=b.x?a.x<b.x:a.y<b.y;
}

bool sort_y(Point a,Point b){
  return a.y!=b.y?a.y<b.y:a.x<b.x;
}

typedef Point Vector;
typedef vector<Point> Polygon;

istream &operator >> (istream &is,Polygon &p){
  for(int i=0;i<(int)p.size();i++) is>>p[i];
  return is;
}

struct Segment{
  Point p1,p2;
  Segment(){}
  Segment(Point p1, Point p2):p1(p1),p2(p2){}
};
typedef Segment Line;

istream &operator >> (istream &is,Segment &s){
  is>>s.p1>>s.p2;
  return is;
}

struct Circle{
  Point c;
  double r;
  Circle(){}
  Circle(Point c,double r):c(c),r(r){}
};

istream &operator >> (istream &is,Circle &c){
  is>>c.c>>c.r;
  return is;
}

double norm(Vector a){
  return a.x*a.x+a.y*a.y;
}
double abs(Vector a){
  return sqrt(norm(a));
}
double dot(Vector a,Vector b){
  return a.x*b.x+a.y*b.y;
}
double cross(Vector a,Vector b){
  return a.x*b.y-a.y*b.x;
}

Point orth(Point p){return Point(-p.y,p.x);}

bool isOrthogonal(Vector a,Vector b){
  return equals(dot(a,b),0.0);
}

bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
  return isOrthogonal(a1-a2,b1-b2);
}

bool isOrthogonal(Segment s1,Segment s2){
  return equals(dot(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

bool isParallel(Vector a,Vector b){
  return equals(cross(a,b),0.0);
}

bool isParallel(Point a1,Point a2,Point b1,Point b2){
  return isParallel(a1-a2,b1-b2);
}

bool isParallel(Segment s1,Segment s2){
  return equals(cross(s1.p2-s1.p1,s2.p2-s2.p1),0.0); 
}

Point project(Segment s,Point p){
  Vector base=s.p2-s.p1;
  double r=dot(p-s.p1,base)/norm(base);
  return s.p1+base*r;
}

Point reflect(Segment s,Point p){
  return p+(project(s,p)-p)*2.0;
}

double arg(Vector p){
  return atan2(p.y,p.x);
}

Vector polar(double a,double r){
  return Point(cos(r)*a,sin(r)*a);
}

int ccw(Point p0,Point p1,Point p2);
bool intersectSS(Point p1,Point p2,Point p3,Point p4);
bool intersectSS(Segment s1,Segment s2);
bool intersectPS(Polygon p,Segment l);
int intersectCC(Circle c1,Circle c2);
bool intersectSC(Segment s,Circle c);
double getDistanceLP(Line l,Point p);
double getDistanceSP(Segment s,Point p);
double getDistanceSS(Segment s1,Segment s2);
Point getCrossPointSS(Segment s1,Segment s2);
Point getCrossPointLL(Line l1,Line l2);
Polygon getCrossPointCL(Circle c,Line l);
Polygon getCrossPointCC(Circle c1,Circle c2);
int contains(Polygon g,Point p);
Polygon andrewScan(Polygon s);
Polygon convex_hull(Polygon ps);
double diameter(Polygon s);
bool isConvex(Polygon p);
double area(Polygon s);
Polygon convexCut(Polygon p,Line l);
Line bisector(Point p1,Point p2);
Vector translate(Vector v,double theta);
vector<Line> corner(Line l1,Line l2);
vector<vector<pair<int, double> > >
segmentArrangement(vector<Segment> &ss, Polygon &ps);
  
int ccw(Point p0,Point p1,Point p2){
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(cross(a,b) > EPS) return CCW_COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS) return CCW_CLOCKWISE;
  if(dot(a,b) < -EPS) return CCW_ONLINE_BACK;
  if(a.norm()<b.norm()) return CCW_ONLINE_FRONT;
  return CCW_ON_SEGMENT;
}

bool intersectSS(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 &&
          ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0 );
}

bool intersectSS(Segment s1,Segment s2){
  return intersectSS(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool intersectPS(Polygon p,Segment l){
  int n=p.size();
  for(int i=0;i<n;i++)
    if(intersectSS(Segment(p[i],p[(i+1)%n]),l)) return 1;
  return 0;
}

int intersectCC(Circle c1,Circle c2){
  if(c1.r<c2.r) swap(c1,c2);
  double d=abs(c1.c-c2.c);
  double r=c1.r+c2.r;
  if(equals(d,r)) return ICC_CIRCUMSCRIBE;
  if(d>r) return ICC_SEPERATE;
  if(equals(d+c2.r,c1.r)) return ICC_INSCRIBE;
  if(d+c2.r<c1.r) return ICC_CONTAIN;
  return ICC_INTERSECT;
}

bool intersectSC(Segment s,Circle c){
  return getDistanceSP(s,c.c)<=c.r;
}

int intersectCS(Circle c,Segment s){
  if(norm(project(s,c.c)-c.c)-c.r*c.r>EPS) return 0;
  double d1=abs(c.c-s.p1),d2=abs(c.c-s.p2);
  if(d1<c.r+EPS&&d2<c.r+EPS) return 0;
  if((d1<c.r-EPS&&d2>c.r+EPS)||(d1>c.r+EPS&&d2<c.r-EPS)) return 1;
  Point h=project(s,c.c);
  if(dot(s.p1-h,s.p2-h)<0) return 2;
  return 0;
}

double getDistanceLP(Line l,Point p){
  return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
  if(dot(s.p2-s.p1,p-s.p1) < 0.0 ) return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0 ) return abs(p-s.p2);
  return getDistanceLP(s,p);
}

double getDistanceSS(Segment s1,Segment s2){
  if(intersectSS(s1,s2)) return 0.0;
  return min(min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
             min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
}

Point getCrossPointSS(Segment s1,Segment s2){
  for(int k=0;k<2;k++){
    if(getDistanceSP(s1,s2.p1)<EPS) return s2.p1; 
    if(getDistanceSP(s1,s2.p2)<EPS) return s2.p2;
    swap(s1,s2);
  }
  Vector base=s2.p2-s2.p1;
  double d1=abs(cross(base,s1.p1-s2.p1));
  double d2=abs(cross(base,s1.p2-s2.p1));
  double t=d1/(d1+d2);
  return s1.p1+(s1.p2-s1.p1)*t;
}

Point getCrossPointLL(Line l1,Line l2){
  double a=cross(l1.p2-l1.p1,l2.p2-l2.p1);
  double b=cross(l1.p2-l1.p1,l1.p2-l2.p1);
  if(abs(a)<EPS&&abs(b)<EPS) return l2.p1;
  return l2.p1+(l2.p2-l2.p1)*(b/a);
}

Polygon getCrossPointCL(Circle c,Line l){
  Polygon ps;
  Point pr=project(l,c.c);
  Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
  if(equals(getDistanceLP(l,c.c),c.r)){
    ps.emplace_back(pr);
    return ps;
  }
  double base=sqrt(c.r*c.r-norm(pr-c.c));
  ps.emplace_back(pr+e*base);
  ps.emplace_back(pr-e*base);
  return ps;
}

Polygon getCrossPointCS(Circle c,Segment s){
  Line l(s);
  Polygon res=getCrossPointCL(c,l);
  if(intersectCS(c,s)==2) return res;
  if(res.size()>1u){
    if(dot(l.p1-res[0],l.p2-res[0])>0) swap(res[0],res[1]);
    res.pop_back();
  }
  return res;
}


Polygon getCrossPointCC(Circle c1,Circle c2){
  Polygon p(2);
  double d=abs(c1.c-c2.c);
  double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
  double t=arg(c2.c-c1.c);
  p[0]=c1.c+polar(c1.r,t+a);
  p[1]=c1.c+polar(c1.r,t-a);
  return p;
}

// IN:2 ON:1 OUT:0
int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Point a=g[i]-p,b=g[(i+1)%n]-p;
    if(fabs(cross(a,b)) < EPS && dot(a,b) < EPS) return 1;
    if(a.y>b.y) swap(a,b);
    if(a.y < EPS && EPS < b.y && cross(a,b) > EPS ) x = !x;
  }
  return (x?2:0);
}

Polygon andrewScan(Polygon s){
  Polygon u,l;
  if(s.size()<3) return s;
  sort(s.begin(),s.end());
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
  for(int i=2;i<(int)s.size();i++){
    for(int n=u.size();n>=2&&ccw(u[n-2],u[n-1],s[i])!=CCW_CLOCKWISE;n--){
      u.pop_back();
    }
    u.push_back(s[i]);
  } 
  for(int i=s.size()-3;i>=0;i--){
    for(int n=l.size();n>=2&&ccw(l[n-2],l[n-1],s[i])!=CCW_CLOCKWISE;n--){
      l.pop_back();
    }
    l.push_back(s[i]);
  }
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--) l.push_back(u[i]);
  return l;
} 

Polygon convex_hull(Polygon ps){
  int n=ps.size();
  sort(ps.begin(),ps.end(),sort_y);
  int k=0;
  Polygon qs(n*2);
  for(int i=0;i<n;i++){
    while(k>1&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0) k--;
    qs[k++]=ps[i];
  }
  for(int i=n-2,t=k;i>=0;i--){
    while(k>t&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0) k--;
    qs[k++]=ps[i];
  }
  qs.resize(k-1);
  return qs;
}

double diameter(Polygon s){
  Polygon p=s;
  int n=p.size();
  if(n==2) return abs(p[0]-p[1]);
  int i=0,j=0;
  for(int k=0;k<n;k++){
    if(p[i]<p[k]) i=k;
    if(!(p[j]<p[k])) j=k;
  }
  double res=0;
  int si=i,sj=j;
  while(i!=sj||j!=si){
    res=max(res,abs(p[i]-p[j]));
    if(cross(p[(i+1)%n]-p[i],p[(j+1)%n]-p[j])<0.0){
      i=(i+1)%n;
    }else{
      j=(j+1)%n;
    }
  }
  return res;
}

bool isConvex(Polygon p){
  bool f=1;
  int n=p.size();
  for(int i=0;i<n;i++){
    int t=ccw(p[(i+n-1)%n],p[i],p[(i+1)%n]);
    f&=t!=CCW_CLOCKWISE;
  }
  return f;
}

double area(Polygon s){
  double res=0;
  for(int i=0;i<(int)s.size();i++){
    res+=cross(s[i],s[(i+1)%s.size()])/2.0;
  }
  return abs(res);
}

double area(Circle c1,Circle c2){
  double d=abs(c1.c-c2.c);
  if(c1.r+c2.r<=d+EPS) return 0;
  if(d<=abs(c1.r-c2.r)){
    double r=min(c1.r,c2.r);
    return PI*r*r;
  }
  double rc=(d*d+c1.r*c1.r-c2.r*c2.r)/(2*d);
  double th=acos(rc/c1.r);
  double ph=acos((d-rc)/c2.r);
  return c1.r*c1.r*th+c2.r*c2.r*ph-d*c1.r*sin(th);
}

Polygon convexCut(Polygon p,Line l){
  Polygon q;
  for(int i=0;i<(int)p.size();i++){
    Point a=p[i],b=p[(i+1)%p.size()];
    if(ccw(l.p1,l.p2,a)!=-1) q.push_back(a);
    if(ccw(l.p1,l.p2,a)*ccw(l.p1,l.p2,b)<0)
      q.push_back(getCrossPointLL(Line(a,b),l));
  }
  return q;
}

Line bisector(Point p1,Point p2){
  Circle c1=Circle(p1,abs(p1-p2)),c2=Circle(p2,abs(p1-p2));
  Polygon p=getCrossPointCC(c1,c2);
  if(cross(p2-p1,p[0]-p1)>0) swap(p[0],p[1]);
  return Line(p[0],p[1]);
}

Vector translate(Vector v,double theta){
  Vector res;
  res.x=cos(theta)*v.x-sin(theta)*v.y;
  res.y=sin(theta)*v.x+cos(theta)*v.y;
  return res;
}

vector<Line> corner(Line l1,Line l2){
  vector<Line> res;
  if(isParallel(l1,l2)){
    double d=getDistanceLP(l1,l2.p1)/2.0;
    Vector v1=l1.p2-l1.p1;
    v1=v1/v1.abs()*d;
    Point p=l2.p1+translate(v1,90.0*(PI/180.0));
    double d1=getDistanceLP(l1,p);
    double d2=getDistanceLP(l2,p);
    if(abs(d1-d2)>d){
      p=l2.p1+translate(v1,-90.0*(PI/180.0));
    }
    res.push_back(Line(p,p+v1));
  }else{
    Point p=getCrossPointLL(l1,l2);
    Vector v1=l1.p2-l1.p1,v2=l2.p2-l2.p1;
    v1=v1/v1.abs();
    v2=v2/v2.abs();
    res.push_back(Line(p,p+(v1+v2)));
    res.push_back(Line(p,p+translate(v1+v2,90.0*(PI/180.0))));
  }
  return res;
}

Polygon tangent(Circle c1,Point p2){
  Circle c2=Circle(p2,sqrt(norm(c1.c-p2)-c1.r*c1.r));
  Polygon p=getCrossPointCC(c1,c2);
  sort(p.begin(),p.end());
  return p;
}

vector<Line> tangent(Circle c1,Circle c2){
  vector<Line> ls;
  if(c1.r<c2.r) swap(c1,c2);
  double g=norm(c1.c-c2.c);
  if(equals(g,0)) return ls;
  Point u=(c2.c-c1.c)/sqrt(g);
  Point v=orth(u);
  for(int s=1;s>=-1;s-=2){
    double h=(c1.r+s*c2.r)/sqrt(g);
    if(equals(1-h*h,0)){
      ls.emplace_back(c1.c+u*c1.r,c1.c+(u+v)*c1.r);
    }else if(1-h*h>0){
      Point uu=u*h,vv=v*sqrt(1-h*h);
      ls.emplace_back(c1.c+(uu+vv)*c1.r,c2.c-(uu+vv)*c2.r*s);
      ls.emplace_back(c1.c+(uu-vv)*c1.r,c2.c-(uu-vv)*c2.r*s);
    }
  }
  
  return ls;
}

double closest_pair(Polygon &a,int l=0,int r=-1){
  if(r<0){
    r=a.size();
    sort(a.begin(),a.end(),sort_x);
  }
  if(r-l<=1) return abs(a[0]-a[1]);
  int m=(l+r)>>1;
  double x=a[m].x;
  double d=min(closest_pair(a,l,m),closest_pair(a,m,r));
  inplace_merge(a.begin()+l,a.begin()+m,a.begin()+r,sort_y);

  Polygon b;
  for(int i=l;i<r;i++){
    if(fabs(a[i].x-x)>=d) continue;
    for(int j=0;j<(int)b.size();j++){
      double dy=a[i].y-next(b.rbegin(),j)->y;
      if(dy>=d) break;
      d=min(d,abs(a[i]-*next(b.rbegin(),j)));
    }
    b.emplace_back(a[i]);
  }
  return d;
}

vector<vector<pair<int, double> > >
segmentArrangement(vector<Segment> &ss, Polygon &ps){
  int n=ss.size();
  for(int i=0;i<n;i++){
    ps.emplace_back(ss[i].p1);
    ps.emplace_back(ss[i].p2);
    for(int j=i+1;j<n;j++)
      if(intersectSS(ss[i],ss[j]))
        ps.emplace_back(getCrossPointSS(ss[i],ss[j]));
  }
  sort(ps.begin(),ps.end());
  ps.erase(unique(ps.begin(),ps.end()),ps.end());

  vector<vector<pair<int, double> > > G(ps.size());
  for(int i=0;i<n;i++){
    vector<pair<double,int> > ls;
    for(int j=0;j<(int)ps.size();j++)
      if(getDistanceSP(ss[i],ps[j])<EPS)
        ls.emplace_back(make_pair(norm(ss[i].p1-ps[j]),j));
      
    sort(ls.begin(),ls.end());
    for(int j=0;j+1<(int)ls.size();j++){
      int a=ls[j].second,b=ls[j+1].second;
      G[a].emplace_back(b,abs(ps[a]-ps[b]));
      G[b].emplace_back(a,abs(ps[a]-ps[b]));
    }
  }
  return G;
}

int manhattanIntersection(vector<Segment> ss,const int INF){
  const int BTM = 0;
  const int LFT = 1;
  const int RGH = 2;
  const int TOP = 3;
  
  int n=ss.size();
  vector<EndPoint> ep;
  for(int i=0;i<n;i++){
    if(ss[i].p1.y==ss[i].p2.y){
      if(ss[i].p1.x>ss[i].p2.x) swap(ss[i].p1,ss[i].p2);
      ep.emplace_back(ss[i].p1,i,LFT);
      ep.emplace_back(ss[i].p2,i,RGH);
    }else{
      if(ss[i].p1.y>ss[i].p2.y) swap(ss[i].p1,ss[i].p2);      
      ep.emplace_back(ss[i].p1,i,BTM);
      ep.emplace_back(ss[i].p2,i,TOP);
    }    
  }   
  sort(ep.begin(),ep.end());

  set<int> bt;
  bt.insert(INF);
  
  int cnt=0;
  for(int i=0;i<n*2;i++){
    if(ep[i].st==TOP){
      bt.erase(ep[i].p.x);
    }else if(ep[i].st==BTM){
      bt.emplace(ep[i].p.x);
    }else if(ep[i].st==LFT){
      auto b=bt.lower_bound(ss[ep[i].seg].p1.x);
      auto e=bt.upper_bound(ss[ep[i].seg].p2.x);
      cnt+=distance(b,e);
    }    
  }
  
  return cnt;
}

double area(Polygon ps,Circle c){
  if(ps.size()<3u) return 0;
  function<double(Circle, Point, Point)> dfs=
    [&](Circle c,Point a,Point b){
      Vector va=c.c-a,vb=c.c-b;
      double f=cross(va,vb),res=0;
      if(equals(f,0.0)) return res;
      if(max(abs(va),abs(vb))<c.r+EPS) return f;
      Vector d(dot(va,vb),cross(va,vb));
      if(getDistanceSP(Segment(a,b),c.c)>c.r-EPS)
        return c.r*c.r*atan2(d.y,d.x);
      auto u=getCrossPointCS(c,Segment(a,b));
      if(u.empty()) return res;
      if(u.size()>1u&&dot(u[1]-u[0],a-u[0])>0) swap(u[0],u[1]);
      u.emplace(u.begin(),a);
      u.emplace_back(b);
      for(int i=1;i<(int)u.size();i++)
        res+=dfs(c,u[i-1],u[i]);
      return res;
    };
  double res=0;
  for(int i=0;i<(int)ps.size();i++)
    res+=dfs(c,ps[i],ps[(i+1)%ps.size()]);
  return res/2;
}



struct Precision{
  Precision(){
    cout<<fixed<<setprecision(12);
  }
}precision_beet;

//INSERT ABOVE HERE
signed main(){
  int n;
  double r;
  cin>>n>>r;
  
  Polygon ps(n);
  for(int i=0;i<n;i++) cin>>ps[i];

  Point g(0,0);
  for(Point p:ps) g=g+p;
  g=g/n;
  
  double ans=0;
  const int MAX = 50;
  auto calc=
    [&](double d)->double{
      double res=0;
      {
        double L=0,R=100;
        for(int k=0;k<MAX;k++){
          double M1=L+(R-L)/3,M2=M1+(R-L)/3;
          Point c1=g+Vector(d,M1);
          Point c2=g+Vector(d,M2);
          double a1=area(ps,Circle(c1,r));
          double a2=area(ps,Circle(c2,r));
          chmax(res,a1);
          chmax(res,a2);
          if(a2<EPS) R=M2;
          else if(a1<a2) L=M1;
          else R=M2;
        }
      }
      {
        double L=0,R=100;
        for(int k=0;k<MAX;k++){
          double M1=L+(R-L)/3,M2=M1+(R-L)/3;
          Point c1=g+Vector(d,-M1);
          Point c2=g+Vector(d,-M2);
          double a1=area(ps,Circle(c1,r));
          double a2=area(ps,Circle(c2,r));
          chmax(res,a1);
          chmax(res,a2);
          if(a2<EPS) R=M2;
          else if(a1<a2) L=M1;
          else R=M2;
        }
      }
      chmax(ans,res);
      //cout<<d<<":"<<res<<endl;
      return res;
    };
  
  {
    double L=0,R=100;
    for(int k=0;k<MAX;k++){
      double M1=L+(R-L)/3,M2=M1+(R-L)/3;
      if(calc(M2)<EPS) R=M2;
      else if(calc(M1)<calc(M2)) L=M1;
      else R=M2;
    }
  }
  {
    double L=0,R=100;
    for(int k=0;k<MAX;k++){
      double M1=L+(R-L)/3,M2=M1+(R-L)/3;
      if(calc(-M2)<EPS) R=M2;
      else if(calc(-M1)<calc(-M2)) L=M1;
      else R=M2;
    }
  }

  cout<<ans<<endl;
  return 0;  
}
accuracy: 1
time_ms: 110
memory_kb: 3652
final_rank: 6

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;

const double EPS = 1e-10;
const double INF = 1e12;
const double PI = acos(-1);
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};
struct C{
    P p;
    double r;
    C(const P& p, const double& r) : p(p), r(r) {}
    C(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return (a.X!=b.X) ? a.X<b.X : a.Y<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}
P unit(const P &p){
    return p/abs(p);
}
P rotate(const P &p, double rad){
    return p *P(cos(rad), sin(rad));
}

bool intersectSP(const L& s, const P &p){
    return abs(cross(s[0]-p, s[1]-p))<EPS  && dot(s[0]-p, s[1]-p)<EPS;
}
bool intersectSS(const L& a, const L& b){
    return ( ccw(a[0],a[1],b[0]) *ccw(a[0],a[1],b[1]) <= 0 ) &&
        ( ccw(b[0],b[1],a[0]) *ccw(b[0],b[1],a[1]) <= 0 );
}
P projection(const L& l, const P& p) {
  double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
  return l[0] + t*(l[0]-l[1]);
}

double distanceLP(const L &l, const P &p) {
  return abs(p - projection(l, p));
}
double distanceSP(const L &s, const P &p) {
  const P r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s[0]-p), abs(s[1]-p));
}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

VP crosspointCL(const C &c, const L &l){
    VP ret;
    P mid = projection(l, c.p);
    double d = distanceLP(l, c.p);
    if(EQ(d, c.r)){
        ret.push_back(mid);
    }else if(d < c.r){
        double len = sqrt(c.r*c.r -d*d);
        ret.push_back(mid +len*unit(l[1]-l[0]));
        ret.push_back(mid -len*unit(l[1]-l[0]));
    }
    return ret;
}
VP crosspointCS(const C &c, const L &s){
    VP ret;
    VP cp = crosspointCL(c,s);
    for(int i=0; i<(int)cp.size(); i++){
        if(intersectSP(s, cp[i])){
            ret.push_back(cp[i]);
        }
    }
    return ret;
}

int in_poly(const P &p, const VP &poly){
    int n = poly.size();
    int ret = -1;
    for(int i=0; i<n; i++){
        P a = poly[i]-p;
        P b = poly[(i+1)%n]-p;
        if(a.Y > b.Y) swap(a,b);
        if(intersectSP(L(a,b), P(0,0))) return 0;
        if(a.Y<=0 && b.Y>0 && cross(a,b)<0) ret = -ret;
    }
    return ret;
}

VP convex(VP v){
    VP ret;
    int n = v.size();
    sort(v.begin(), v.end());
    for(int i=0; i<n; i++){
        while((int)ret.size()>1 && cross(ret.back()-ret[ret.size()-2], v[i]-ret.back()) < EPS){
            ret.pop_back();
        }
        ret.push_back(v[i]);
    }
    int t = ret.size();
    for(int i=n-2; i>=0; i--){
        while((int)ret.size()>t && cross(ret.back()-ret[ret.size()-2], v[i]-ret.back()) < EPS){
            ret.pop_back();
        }
        ret.push_back(v[i]);
    }
    if((int)ret.size() > 1) ret.pop_back();
    return ret;
}

double commonarea_circle_convex(C c, VP poly){
    int n = poly.size();
    for(int i=0; i<n; i++) poly[i] -= c.p;
    c.p = P(0, 0);
    
    VP cp;
    for(int i=0; i<n; i++){
        L edge(poly[i], poly[(i+1)%n]);
        VP ret = crosspointCS(c, edge);
        cp.insert(cp.begin(), ret.begin(), ret.end());
        if(abs(poly[i]) < c.r) cp.push_back(poly[i]);
    }
    sort(cp.begin(), cp.end());
    cp.erase(unique(cp.begin(), cp.end()), cp.end());
    
    double res = 0;
    VP v = convex(cp);
    int m = v.size();
    for(int i=0; i<m; i++){
        P curr = v[i];
        P next = v[(i+1)%m];
        if(EQ(abs(curr), c.r) && EQ(abs(next), c.r)
           && in_poly(c.r *unit(next -curr)*P(0,-1), poly) > 0){
            double theta = arg(next /curr);
            if(theta < 0) theta += 2*PI;
            res += c.r*c.r *theta /2;
        }else{
            res += cross(curr, next) /2;
        }
    }
    return res;
}


int main(){
    int n,r;
    cin >> n >> r;
    VP poly(n);
    int xmax=0, xmin=100;
    for(int i=0; i<n; i++){
        int x,y;
        cin >> x >> y;
        poly[i] = P(x, y);
        xmax = max(xmax, x);
        xmin = min(xmin, x);
    }

    double ans = 0;
    double lb=xmin, ub=xmax;
    for(int rep=0; rep<50; rep++){
        double mid[2] = {(2*lb +ub)/3, (lb +2*ub)/3};
        double area[2];
        for(int i=0; i<2; i++){
            vector<double> bound;
            double x = mid[i];
            L div(P(x, -INF), P(x, INF));
            for(int j=0; j<n; j++){
                L edge(poly[j], poly[(j+1)%n]);
                if(!isParallel(div, edge) && intersectSS(div, edge)){
                    bound.push_back(crosspointLL(div, edge).Y);
                }
            }
            sort(bound.begin(), bound.end());
            double lb = bound[0], ub = bound.back();
            for(int rep=0; rep<50; rep++){
                double mid[2] = {(2*lb +ub)/3, (lb +2*ub)/3};
                double area[2];
                for(int i=0; i<2; i++){
                    area[i] = commonarea_circle_convex(C(P(x, mid[i]), r), poly);
                }
                if(area[0] > area[1]){
                    ub = mid[1];
                }else{
                    lb = mid[0];
                }
            }
            area[i] = commonarea_circle_convex(C(P(x, lb), r), poly);
            ans = max(ans, area[i]);
        }
        if(area[0] > area[1]){
            ub = mid[1];
        }else{
            lb = mid[0];
        }
    }
    cout << fixed;
    cout << setprecision(10);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3548
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

using Real = double;
using Point = complex< Real >;
const Real EPS = 1e-8, PI = acos(-1);

inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; }

Point operator*(const Point &p, const Real &d) {
  return Point(real(p) * d, imag(p) * d);
}

istream &operator>>(istream &is, Point &p) {
  Real a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}

ostream &operator<<(ostream &os, Point &p) {
  os << fixed << setprecision(10) << p.real() << " " << p.imag();
}

Point rotate(Real theta, const Point &p) {
  return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

Real radian_to_degree(Real r) {
  return (r * 180.0 / PI);
}

Real degree_to_radian(Real d) {
  return (d * PI / 180.0);
}

Real get_angle(const Point &a, const Point &b, const Point &c) {
  const Point v(b - a), w(c - b);
  Real alpha = atan2(v.imag(), v.real()), beta = atan2(w.imag(), w.real());
  if(alpha > beta) swap(alpha, beta);
  Real theta = (beta - alpha);
  return min(theta, 2 * acos(-1) - theta);
}

namespace std {
  bool operator<(const Point &a, const Point &b) {
    return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
  }
}


struct Line {
  Point a, b;

  Line() = default;

  Line(Point a, Point b) : a(a), b(b) {}

  Line(Real A, Real B, Real C) // Ax + By = C
  {
    if(eq(A, 0)) a = Point(0, C / B), b = Point(1, C / B);
    else if(eq(B, 0)) b = Point(C / A, 0), b = Point(C / A, 1);
    else a = Point(0, C / B), b = Point(C / A, 0);
  }

  friend ostream &operator<<(ostream &os, Line &p) {
    return os << p.a << " to " << p.b;
  }

  friend istream &operator>>(istream &is, Line &a) {
    return is >> a.a >> a.b;
  }
};

struct Segment : Line {
  Segment() = default;

  Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
  Point p;
  Real r;

  Circle() = default;

  Circle(Point p, Real r) : p(p), r(r) {}
};

using Points = vector< Point >;
using Polygon = vector< Point >;
using Segments = vector< Segment >;
using Lines = vector< Line >;
using Circles = vector< Circle >;

Real cross(const Point &a, const Point &b) {
  return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point &a, const Point &b) {
  return real(a) * real(b) + imag(a) * imag(b);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
int ccw(const Point &a, Point b, Point c) {
  b = b - a, c = c - a;
  if(cross(b, c) > EPS) return +1;  // "COUNTER_CLOCKWISE"
  if(cross(b, c) < -EPS) return -1; // "CLOCKWISE"
  if(dot(b, c) < 0) return +2;      // "ONLINE_BACK"
  if(norm(b) < norm(c)) return -2;  // "ONLINE_FRONT"
  return 0;                         // "ON_SEGMENT"
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool parallel(const Line &a, const Line &b) {
  return eq(cross(a.b - a.a, b.b - b.a), 0.0);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool orthogonal(const Line &a, const Line &b) {
  return eq(dot(a.a - a.b, b.a - b.b), 0.0);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line &l, const Point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line &l, const Point &p) {
  return p + (projection(l, p) - p) * 2.0;
}

bool intersect(const Line &l, const Point &p) {
  return abs(ccw(l.a, l.b, p)) != 1;
}

bool intersect(const Line &l, const Line &m) {
  return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}

bool intersect(const Segment &s, const Point &p) {
  return ccw(s.a, s.b, p) == 0;
}

bool intersect(const Line &l, const Segment &s) {
  return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

Real distance(const Line &l, const Point &p);

bool intersect(const Circle &c, const Line &l) {
  return distance(l, c.p) <= c.r + EPS;
}

bool intersect(const Circle &c, const Point &p) {
  return abs(abs(p - c.p) - c.r) < EPS;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
bool intersect(const Segment &s, const Segment &t) {
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

int intersect(const Circle &c, const Segment &l) {
  if(norm(projection(l, c.p) - c.p) - c.r * c.r > EPS) return 0;
  auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b);
  if(d1 < c.r + EPS && d2 < c.r + EPS) return 0;
  if(d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS) return 1;
  const Point h = projection(l, c.p);
  if(dot(l.a - h, l.b - h) < 0) return 2;
  return 0;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp
int intersect(Circle c1, Circle c2) {
  if(c1.r < c2.r) swap(c1, c2);
  Real d = abs(c1.p - c2.p);
  if(c1.r + c2.r < d) return 4;
  if(eq(c1.r + c2.r, d)) return 3;
  if(c1.r - c2.r < d) return 2;
  if(eq(c1.r - c2.r, d)) return 1;
  return 0;
}

Real distance(const Point &a, const Point &b) {
  return abs(a - b);
}

Real distance(const Line &l, const Point &p) {
  return abs(p - projection(l, p));
}

Real distance(const Line &l, const Line &m) {
  return intersect(l, m) ? 0 : distance(l, m.a);
}

Real distance(const Segment &s, const Point &p) {
  Point r = projection(s, p);
  if(intersect(s, r)) return abs(r - p);
  return min(abs(s.a - p), abs(s.b - p));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b) {
  if(intersect(a, b)) return 0;
  return min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

Real distance(const Line &l, const Segment &s) {
  if(intersect(l, s)) return 0;
  return min(distance(l, s.a), distance(l, s.b));
}

Point crosspoint(const Line &l, const Line &m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) {
  return crosspoint(Line(l), Line(m));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
pair< Point, Point > crosspoint(const Circle &c, const Line l) {
  Point pr = projection(l, c.p);
  Point e = (l.b - l.a) / abs(l.b - l.a);
  if(eq(distance(l, c.p), c.r)) return {pr, pr};
  double base = sqrt(c.r * c.r - norm(pr - c.p));
  return {pr - e * base, pr + e * base};
}

pair< Point, Point > crosspoint(const Circle &c, const Segment &l) {
  Line aa = Line(l.a, l.b);
  if(intersect(c, l) == 2) return crosspoint(c, aa);
  auto ret = crosspoint(c, aa);
  if(dot(l.a - ret.first, l.b - ret.first) < 0) ret.second = ret.first;
  else ret.first = ret.second;
  return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
pair< Point, Point > crosspoint(const Circle &c1, const Circle &c2) {
  Real d = abs(c1.p - c2.p);
  Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
  Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
  Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
  Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
  return {p1, p2};
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
pair< Point, Point > tangent(const Circle &c1, const Point &p2) {
  return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r)));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
Lines tangent(Circle c1, Circle c2) {
  Lines ret;
  if(c1.r < c2.r) swap(c1, c2);
  Real g = norm(c1.p - c2.p);
  if(eq(g, 0)) return ret;
  Point u = (c2.p - c1.p) / sqrt(g);
  Point v = rotate(PI * 0.5, u);
  for(int s : {-1, 1}) {
    Real h = (c1.r + s * c2.r) / sqrt(g);
    if(eq(1 - h * h, 0)) {
      ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
    } else if(1 - h * h > 0) {
      Point uu = u * h, vv = v * sqrt(1 - h * h);
      ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
      ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
    }
  }
  return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool is_convex(const Polygon &p) {
  int n = (int) p.size();
  for(int i = 0; i < n; i++) {
    if(ccw(p[(i + n - 1) % n], p[i], p[(i + 1) % n]) == -1) return false;
  }
  return true;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
Polygon convex_hull(Polygon &p) {
  int n = (int) p.size(), k = 0;
  if(n <= 2) return p;
  sort(p.begin(), p.end());
  vector< Point > ch(2 * n);
  for(int i = 0; i < n; ch[k++] = p[i++]) {
    while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
  }
  for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
    while(k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
  }
  ch.resize(k - 1);
  return ch;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
enum {
  OUT, ON, IN
};

int contains(const Polygon &Q, const Point &p) {
  bool in = false;
  for(int i = 0; i < Q.size(); i++) {
    Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
    if(a.imag() > b.imag()) swap(a, b);
    if(a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in;
    if(cross(a, b) == 0 && dot(a, b) <= 0) return ON;
  }
  return in ? IN : OUT;
}


// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
void merge_segments(vector< Segment > &segs) {

  auto merge_if_able = [](Segment &s1, const Segment &s2) {
    if(abs(cross(s1.b - s1.a, s2.b - s2.a)) > EPS) return false;
    if(ccw(s1.a, s2.a, s1.b) == 1 || ccw(s1.a, s2.a, s1.b) == -1) return false;
    if(ccw(s1.a, s1.b, s2.a) == -2 || ccw(s2.a, s2.b, s1.a) == -2) return false;
    s1 = Segment(min(s1.a, s2.a), max(s1.b, s2.b));
    return true;
  };

  for(int i = 0; i < segs.size(); i++) {
    if(segs[i].b < segs[i].a) swap(segs[i].a, segs[i].b);
  }
  for(int i = 0; i < segs.size(); i++) {
    for(int j = i + 1; j < segs.size(); j++) {
      if(merge_if_able(segs[i], segs[j])) {
        segs[j--] = segs.back(), segs.pop_back();
      }
    }
  }
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
vector< vector< int > > segment_arrangement(vector< Segment > &segs, vector< Point > &ps) {
  vector< vector< int > > g;
  int N = (int) segs.size();
  for(int i = 0; i < N; i++) {
    ps.emplace_back(segs[i].a);
    ps.emplace_back(segs[i].b);
    for(int j = i + 1; j < N; j++) {
      const Point p1 = segs[i].b - segs[i].a;
      const Point p2 = segs[j].b - segs[j].a;
      if(cross(p1, p2) == 0) continue;
      if(intersect(segs[i], segs[j])) {
        ps.emplace_back(crosspoint(segs[i], segs[j]));
      }
    }
  }
  sort(begin(ps), end(ps));
  ps.erase(unique(begin(ps), end(ps)), end(ps));

  int M = (int) ps.size();
  g.resize(M);
  for(int i = 0; i < N; i++) {
    vector< int > vec;
    for(int j = 0; j < M; j++) {
      if(intersect(segs[i], ps[j])) {
        vec.emplace_back(j);
      }
    }
    for(int j = 1; j < vec.size(); j++) {
      g[vec[j - 1]].push_back(vec[j]);
      g[vec[j]].push_back(vec[j - 1]);
    }
  }
  return (g);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C
Polygon convex_cut(const Polygon &U, Line l) {
  Polygon ret;
  for(int i = 0; i < U.size(); i++) {
    Point now = U[i], nxt = U[(i + 1) % U.size()];
    if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
    if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) {
      ret.push_back(crosspoint(Line(now, nxt), l));
    }
  }
  return (ret);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A
Real area2(const Polygon &p) {
  Real A = 0;
  for(int i = 0; i < p.size(); ++i) {
    A += cross(p[i], p[(i + 1) % p.size()]);
  }
  return A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_H
Real area2(const Polygon &p, const Circle &c) {
  if(p.size() < 3) return 0.0;
  function< Real(Circle, Point, Point) > cross_area = [&](const Circle &c, const Point &a, const Point &b) {
    Point va = c.p - a, vb = c.p - b;
    Real f = cross(va, vb), ret = 0.0;
    if(eq(f, 0.0)) return ret;
    if(max(abs(va), abs(vb)) < c.r + EPS) return f;
    if(distance(Segment(a, b), c.p) > c.r - EPS) return c.r * c.r * arg(vb * conj(va));
    auto u = crosspoint(c, Segment(a, b));
    vector< Point > tot{a, u.first, u.second, b};
    for(int i = 0; i + 1 < tot.size(); i++) {
      ret += cross_area(c, tot[i], tot[i + 1]);
    }
    return ret;
  };
  Real A = 0;
  for(int i = 0; i < p.size(); i++) {
    A += cross_area(c, p[i], p[(i + 1) % p.size()]);
  }
  return A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B
Real convex_diameter(const Polygon &p) {
  int N = (int) p.size();
  int is = 0, js = 0;
  for(int i = 1; i < N; i++) {
    if(p[i].imag() > p[is].imag()) is = i;
    if(p[i].imag() < p[js].imag()) js = i;
  }
  Real maxdis = norm(p[is] - p[js]);

  int maxi, maxj, i, j;
  i = maxi = is;
  j = maxj = js;
  do {
    if(cross(p[(i + 1) % N] - p[i], p[(j + 1) % N] - p[j]) >= 0) {
      j = (j + 1) % N;
    } else {
      i = (i + 1) % N;
    }
    if(norm(p[i] - p[j]) > maxdis) {
      maxdis = norm(p[i] - p[j]);
      maxi = i;
      maxj = j;
    }
  } while(i != is || j != js);
  return sqrt(maxdis);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_5_A
Real closest_pair(Points ps) {
  if(ps.size() <= 1) throw (0);
  sort(begin(ps), end(ps));

  auto compare_y = [&](const Point &a, const Point &b) {
    return imag(a) < imag(b);
  };
  vector< Point > beet(ps.size());
  const Real INF = 1e18;

  function< Real(int, int) > rec = [&](int left, int right) {
    if(right - left <= 1) return INF;
    int mid = (left + right) >> 1;
    auto x = real(ps[mid]);
    auto ret = min(rec(left, mid), rec(mid, right));
    inplace_merge(begin(ps) + left, begin(ps) + mid, begin(ps) + right, compare_y);
    int ptr = 0;
    for(int i = left; i < right; i++) {
      if(abs(real(ps[i]) - x) >= ret) continue;
      for(int j = 0; j < ptr; j++) {
        auto luz = ps[i] - beet[ptr - j - 1];
        if(imag(luz) >= ret) break;
        ret = min(ret, abs(luz));
      }
      beet[ptr++] = ps[i];
    }
    return ret;
  };
  return rec(0, (int) ps.size());
}


int main() {
  int N, R;
  cin >> N >> R;
  Polygon ps(N);

  double ret = 0.0;
  auto check = [&](double x) {
    double vv = 0.0;
    double low = 1e9, high = -1e9;
    Line l = Line(Point(x, 0), Point(x, 1));
    for(int i = 0; i < N; i++) {
      if(intersect(l, Segment(ps[i], ps[(i + 1) % N]))) {
        auto point = crosspoint(l, Segment(ps[i], ps[(i + 1) % N]));
        low = min(low, imag(point));
        high = max(high, imag(point));
      }
    }

    for(int i = 0; i < 100; i++) {
      double left = (low * 2 + high) / 3;
      double right = (low + high * 2) / 3;

      auto A = area2(ps, Circle(Point(x, left), R));
      auto B = area2(ps, Circle(Point(x, right), R));
      vv = max(vv, max(A, B));
      if(A < B) low = left;
      else high = right;
    }
    ret = max(ret, vv);
    return (vv);
  };


  double low = 1e9, high = -1e9;
  for(int i = 0; i < N; i++) {
    cin >> ps[i];
    low = min(low, real(ps[i]));
    high = max(high, real(ps[i]));
  }

  for(int i = 0; i < 100; i++) {
    double left = (low * 2 + high) / 3;
    double right = (low + high * 2) / 3;
    if(check(left) < check(right)) low = left;
    else high = right;
  }
  cout << fixed << setprecision(10) << ret * 0.5 << endl;
}
accuracy: 1
time_ms: 170
memory_kb: 3636
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

using Real = double;
using Point = complex< Real >;
const Real EPS = 1e-8, PI = acos(-1);

inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; }

Point operator*(const Point &p, const Real &d) {
  return Point(real(p) * d, imag(p) * d);
}

istream &operator>>(istream &is, Point &p) {
  Real a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}

ostream &operator<<(ostream &os, Point &p) {
  os << fixed << setprecision(10) << p.real() << " " << p.imag();
}

Point rotate(Real theta, const Point &p) {
  return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

Real radian_to_degree(Real r) {
  return (r * 180.0 / PI);
}

Real degree_to_radian(Real d) {
  return (d * PI / 180.0);
}

Real get_angle(const Point &a, const Point &b, const Point &c) {
  const Point v(b - a), w(c - b);
  Real alpha = atan2(v.imag(), v.real()), beta = atan2(w.imag(), w.real());
  if(alpha > beta) swap(alpha, beta);
  Real theta = (beta - alpha);
  return min(theta, 2 * acos(-1) - theta);
}

namespace std {
  bool operator<(const Point &a, const Point &b) {
    return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
  }
}


struct Line {
  Point a, b;

  Line() = default;

  Line(Point a, Point b) : a(a), b(b) {}

  Line(Real A, Real B, Real C) // Ax + By = C
  {
    if(eq(A, 0)) a = Point(0, C / B), b = Point(1, C / B);
    else if(eq(B, 0)) b = Point(C / A, 0), b = Point(C / A, 1);
    else a = Point(0, C / B), b = Point(C / A, 0);
  }

  friend ostream &operator<<(ostream &os, Line &p) {
    return os << p.a << " to " << p.b;
  }

  friend istream &operator>>(istream &is, Line &a) {
    return is >> a.a >> a.b;
  }
};

struct Segment : Line {
  Segment() = default;

  Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
  Point p;
  Real r;

  Circle() = default;

  Circle(Point p, Real r) : p(p), r(r) {}
};

using Points = vector< Point >;
using Polygon = vector< Point >;
using Segments = vector< Segment >;
using Lines = vector< Line >;
using Circles = vector< Circle >;

Real cross(const Point &a, const Point &b) {
  return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point &a, const Point &b) {
  return real(a) * real(b) + imag(a) * imag(b);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
int ccw(const Point &a, Point b, Point c) {
  b = b - a, c = c - a;
  if(cross(b, c) > EPS) return +1;  // "COUNTER_CLOCKWISE"
  if(cross(b, c) < -EPS) return -1; // "CLOCKWISE"
  if(dot(b, c) < 0) return +2;      // "ONLINE_BACK"
  if(norm(b) < norm(c)) return -2;  // "ONLINE_FRONT"
  return 0;                         // "ON_SEGMENT"
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool parallel(const Line &a, const Line &b) {
  return eq(cross(a.b - a.a, b.b - b.a), 0.0);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool orthogonal(const Line &a, const Line &b) {
  return eq(dot(a.a - a.b, b.a - b.b), 0.0);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line &l, const Point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line &l, const Point &p) {
  return p + (projection(l, p) - p) * 2.0;
}

bool intersect(const Line &l, const Point &p) {
  return abs(ccw(l.a, l.b, p)) != 1;
}

bool intersect(const Line &l, const Line &m) {
  return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}

bool intersect(const Segment &s, const Point &p) {
  return ccw(s.a, s.b, p) == 0;
}

bool intersect(const Line &l, const Segment &s) {
  return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

Real distance(const Line &l, const Point &p);

bool intersect(const Circle &c, const Line &l) {
  return distance(l, c.p) <= c.r + EPS;
}

bool intersect(const Circle &c, const Point &p) {
  return abs(abs(p - c.p) - c.r) < EPS;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
bool intersect(const Segment &s, const Segment &t) {
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

int intersect(const Circle &c, const Segment &l) {
  if(norm(projection(l, c.p) - c.p) - c.r * c.r > EPS) return 0;
  auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b);
  if(d1 < c.r + EPS && d2 < c.r + EPS) return 0;
  if(d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS) return 1;
  const Point h = projection(l, c.p);
  if(dot(l.a - h, l.b - h) < 0) return 2;
  return 0;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp
int intersect(Circle c1, Circle c2) {
  if(c1.r < c2.r) swap(c1, c2);
  Real d = abs(c1.p - c2.p);
  if(c1.r + c2.r < d) return 4;
  if(eq(c1.r + c2.r, d)) return 3;
  if(c1.r - c2.r < d) return 2;
  if(eq(c1.r - c2.r, d)) return 1;
  return 0;
}

Real distance(const Point &a, const Point &b) {
  return abs(a - b);
}

Real distance(const Line &l, const Point &p) {
  return abs(p - projection(l, p));
}

Real distance(const Line &l, const Line &m) {
  return intersect(l, m) ? 0 : distance(l, m.a);
}

Real distance(const Segment &s, const Point &p) {
  Point r = projection(s, p);
  if(intersect(s, r)) return abs(r - p);
  return min(abs(s.a - p), abs(s.b - p));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b) {
  if(intersect(a, b)) return 0;
  return min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

Real distance(const Line &l, const Segment &s) {
  if(intersect(l, s)) return 0;
  return min(distance(l, s.a), distance(l, s.b));
}

Point crosspoint(const Line &l, const Line &m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) {
  return crosspoint(Line(l), Line(m));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
pair< Point, Point > crosspoint(const Circle &c, const Line l) {
  Point pr = projection(l, c.p);
  Point e = (l.b - l.a) / abs(l.b - l.a);
  if(eq(distance(l, c.p), c.r)) return {pr, pr};
  double base = sqrt(c.r * c.r - norm(pr - c.p));
  return {pr - e * base, pr + e * base};
}

pair< Point, Point > crosspoint(const Circle &c, const Segment &l) {
  Line aa = Line(l.a, l.b);
  if(intersect(c, l) == 2) return crosspoint(c, aa);
  auto ret = crosspoint(c, aa);
  if(dot(l.a - ret.first, l.b - ret.first) < 0) ret.second = ret.first;
  else ret.first = ret.second;
  return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
pair< Point, Point > crosspoint(const Circle &c1, const Circle &c2) {
  Real d = abs(c1.p - c2.p);
  Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
  Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
  Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
  Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
  return {p1, p2};
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
pair< Point, Point > tangent(const Circle &c1, const Point &p2) {
  return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r)));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
Lines tangent(Circle c1, Circle c2) {
  Lines ret;
  if(c1.r < c2.r) swap(c1, c2);
  Real g = norm(c1.p - c2.p);
  if(eq(g, 0)) return ret;
  Point u = (c2.p - c1.p) / sqrt(g);
  Point v = rotate(PI * 0.5, u);
  for(int s : {-1, 1}) {
    Real h = (c1.r + s * c2.r) / sqrt(g);
    if(eq(1 - h * h, 0)) {
      ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
    } else if(1 - h * h > 0) {
      Point uu = u * h, vv = v * sqrt(1 - h * h);
      ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
      ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
    }
  }
  return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool is_convex(const Polygon &p) {
  int n = (int) p.size();
  for(int i = 0; i < n; i++) {
    if(ccw(p[(i + n - 1) % n], p[i], p[(i + 1) % n]) == -1) return false;
  }
  return true;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
Polygon convex_hull(Polygon &p) {
  int n = (int) p.size(), k = 0;
  if(n <= 2) return p;
  sort(p.begin(), p.end());
  vector< Point > ch(2 * n);
  for(int i = 0; i < n; ch[k++] = p[i++]) {
    while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
  }
  for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
    while(k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
  }
  ch.resize(k - 1);
  return ch;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
enum {
  OUT, ON, IN
};

int contains(const Polygon &Q, const Point &p) {
  bool in = false;
  for(int i = 0; i < Q.size(); i++) {
    Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
    if(a.imag() > b.imag()) swap(a, b);
    if(a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in;
    if(cross(a, b) == 0 && dot(a, b) <= 0) return ON;
  }
  return in ? IN : OUT;
}


// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
void merge_segments(vector< Segment > &segs) {

  auto merge_if_able = [](Segment &s1, const Segment &s2) {
    if(abs(cross(s1.b - s1.a, s2.b - s2.a)) > EPS) return false;
    if(ccw(s1.a, s2.a, s1.b) == 1 || ccw(s1.a, s2.a, s1.b) == -1) return false;
    if(ccw(s1.a, s1.b, s2.a) == -2 || ccw(s2.a, s2.b, s1.a) == -2) return false;
    s1 = Segment(min(s1.a, s2.a), max(s1.b, s2.b));
    return true;
  };

  for(int i = 0; i < segs.size(); i++) {
    if(segs[i].b < segs[i].a) swap(segs[i].a, segs[i].b);
  }
  for(int i = 0; i < segs.size(); i++) {
    for(int j = i + 1; j < segs.size(); j++) {
      if(merge_if_able(segs[i], segs[j])) {
        segs[j--] = segs.back(), segs.pop_back();
      }
    }
  }
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
vector< vector< int > > segment_arrangement(vector< Segment > &segs, vector< Point > &ps) {
  vector< vector< int > > g;
  int N = (int) segs.size();
  for(int i = 0; i < N; i++) {
    ps.emplace_back(segs[i].a);
    ps.emplace_back(segs[i].b);
    for(int j = i + 1; j < N; j++) {
      const Point p1 = segs[i].b - segs[i].a;
      const Point p2 = segs[j].b - segs[j].a;
      if(cross(p1, p2) == 0) continue;
      if(intersect(segs[i], segs[j])) {
        ps.emplace_back(crosspoint(segs[i], segs[j]));
      }
    }
  }
  sort(begin(ps), end(ps));
  ps.erase(unique(begin(ps), end(ps)), end(ps));

  int M = (int) ps.size();
  g.resize(M);
  for(int i = 0; i < N; i++) {
    vector< int > vec;
    for(int j = 0; j < M; j++) {
      if(intersect(segs[i], ps[j])) {
        vec.emplace_back(j);
      }
    }
    for(int j = 1; j < vec.size(); j++) {
      g[vec[j - 1]].push_back(vec[j]);
      g[vec[j]].push_back(vec[j - 1]);
    }
  }
  return (g);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C
Polygon convex_cut(const Polygon &U, Line l) {
  Polygon ret;
  for(int i = 0; i < U.size(); i++) {
    Point now = U[i], nxt = U[(i + 1) % U.size()];
    if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
    if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) {
      ret.push_back(crosspoint(Line(now, nxt), l));
    }
  }
  return (ret);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A
Real area2(const Polygon &p) {
  Real A = 0;
  for(int i = 0; i < p.size(); ++i) {
    A += cross(p[i], p[(i + 1) % p.size()]);
  }
  return A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_H
Real area2(const Polygon &p, const Circle &c) {
  if(p.size() < 3) return 0.0;
  function< Real(Circle, Point, Point) > cross_area = [&](const Circle &c, const Point &a, const Point &b) {
    Point va = c.p - a, vb = c.p - b;
    Real f = cross(va, vb), ret = 0.0;
    if(eq(f, 0.0)) return ret;
    if(max(abs(va), abs(vb)) < c.r + EPS) return f;
    if(distance(Segment(a, b), c.p) > c.r - EPS) return c.r * c.r * arg(vb * conj(va));
    auto u = crosspoint(c, Segment(a, b));
    vector< Point > tot{a, u.first, u.second, b};
    for(int i = 0; i + 1 < tot.size(); i++) {
      ret += cross_area(c, tot[i], tot[i + 1]);
    }
    return ret;
  };
  Real A = 0;
  for(int i = 0; i < p.size(); i++) {
    A += cross_area(c, p[i], p[(i + 1) % p.size()]);
  }
  return A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B
Real convex_diameter(const Polygon &p) {
  int N = (int) p.size();
  int is = 0, js = 0;
  for(int i = 1; i < N; i++) {
    if(p[i].imag() > p[is].imag()) is = i;
    if(p[i].imag() < p[js].imag()) js = i;
  }
  Real maxdis = norm(p[is] - p[js]);

  int maxi, maxj, i, j;
  i = maxi = is;
  j = maxj = js;
  do {
    if(cross(p[(i + 1) % N] - p[i], p[(j + 1) % N] - p[j]) >= 0) {
      j = (j + 1) % N;
    } else {
      i = (i + 1) % N;
    }
    if(norm(p[i] - p[j]) > maxdis) {
      maxdis = norm(p[i] - p[j]);
      maxi = i;
      maxj = j;
    }
  } while(i != is || j != js);
  return sqrt(maxdis);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_5_A
Real closest_pair(Points ps) {
  if(ps.size() <= 1) throw (0);
  sort(begin(ps), end(ps));

  auto compare_y = [&](const Point &a, const Point &b) {
    return imag(a) < imag(b);
  };
  vector< Point > beet(ps.size());
  const Real INF = 1e18;

  function< Real(int, int) > rec = [&](int left, int right) {
    if(right - left <= 1) return INF;
    int mid = (left + right) >> 1;
    auto x = real(ps[mid]);
    auto ret = min(rec(left, mid), rec(mid, right));
    inplace_merge(begin(ps) + left, begin(ps) + mid, begin(ps) + right, compare_y);
    int ptr = 0;
    for(int i = left; i < right; i++) {
      if(abs(real(ps[i]) - x) >= ret) continue;
      for(int j = 0; j < ptr; j++) {
        auto luz = ps[i] - beet[ptr - j - 1];
        if(imag(luz) >= ret) break;
        ret = min(ret, abs(luz));
      }
      beet[ptr++] = ps[i];
    }
    return ret;
  };
  return rec(0, (int) ps.size());
}


int main() {
  int N, R;
  cin >> N >> R;
  Polygon ps(N);

  double ret = 0.0;
  auto check = [&](double x) {
    double vv = 0.0;
    double low = 1e9, high = -1e9;
    Line l = Line(Point(x, 0), Point(x, 1));
    for(int i = 0; i < N; i++) {
      if(intersect(l, Segment(ps[i], ps[(i + 1) % N]))) {
        auto point = crosspoint(l, Segment(ps[i], ps[(i + 1) % N]));
        low = min(low, imag(point));
        high = max(high, imag(point));
      }
    }

    for(int i = 0; i < 300; i++) {
      double left = (low * 2 + high) / 3;
      double right = (low + high * 2) / 3;

      auto A = area2(ps, Circle(Point(x, left), R));
      auto B = area2(ps, Circle(Point(x, right), R));
      vv = max(vv, max(A, B));
      if(A < B) low = left;
      else high = right;
    }
    ret = max(ret, vv);
    return (vv);
  };


  double low = 1e9, high = -1e9;
  for(int i = 0; i < N; i++) {
    cin >> ps[i];
    low = min(low, real(ps[i]));
    high = max(high, real(ps[i]));
  }

  for(int i = 0; i < 300; i++) {
    double left = (low * 2 + high) / 3;
    double right = (low + high * 2) / 3;
    if(check(left) < check(right)) low = left;
    else high = right;
  }
  cout << fixed << setprecision(10) << ret * 0.5 << endl;
}
accuracy: 1
time_ms: 1430
memory_kb: 3636
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define cout if (1) cout

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

// area de calota na altura h : 2.pi.R.h
// volume de calota na altura h : pi.h/6 * (3r^2 + h^2)

// XXX marks risky behaviour and TODO marks untested functions
typedef double cood; cood eps = 1e-8; cood inf = 1./0.;
const double pi = acos(-1.);
inline ll sq (ll x) { return x*x; }
inline double sq (double x) { return x*x; }
struct vec { // vector
	cood x, y;
	vec () : x(0), y(0) {} vec (cood a, cood b) : x(a), y(b) {}
	inline vec operator - (vec o) { return vec(x - o.x, y - o.y); }
	inline vec operator + (vec o) { return vec(x + o.x, y + o.y); }
	inline vec operator * (cood o) { return vec(x * o, y * o); }
	inline vec operator / (cood o) { return vec(x / o, y / o); }
	inline cood operator ^ (vec o) { return x * o.y - y * o.x; }
	inline cood operator * (vec o) { return x * o.x + y * o.y; }

	inline cood cross (vec a, vec b) { return ((*this)-a) ^ ((*this)-b); } // |(this)a|sen(angle)
	inline cood inner (vec a, vec b) { return ((*this)-a) * ((*this)-b); } // |(this)a|cos(angle)
	inline double angle (vec a, vec b) { return atan2(cross(a,b),inner(a,b)); } // ccw angle from (this)a to (this)b in range [-pi,pi]
	inline int ccw (vec a, vec b) { cood o = cross(a,b); return (eps < o) - (o < -eps); } // this is to the (1 left, 0 over, -1 right) of ab
	inline int dir (vec a, vec b) { cood o = inner(a,b); return (eps < o) - (o < -eps); } // a(this) is to the (1 same, 0 none, -1 opposite) direction of ab
	inline cood sq (vec o = vec()) { return inner(o,o); }
	inline double nr (vec o = vec()) { return sqrt(sq(o)); }
	inline vec proj (vec a, vec b) { return a + (b-a)*(a.inner((*this),b) / a.sq(b)); }
	inline vec rotate (double a) { return vec(cos(a) * x - sin(a) * y, sin(a) * x + cos(a) * y); } // ccw by a radians
	inline vec rot90 () { return vec(-y,x); } // rotate(pi/2)

	inline bool operator < (const vec & o) const { return (x != o.x)?(x < o.x):(y > o.y); } // lex compare (inc x, dec y)
	// full ccw angle from compare beginning upwards (this+(0,1)) around (*this)
	// incresing distance on ties
	bool compare (vec a, vec b) { 
		if ((a < (*this)) != (b < (*this))) return a < (*this);
		int o = ccw(a,b); if (o) return o > 0;
		return a.dir((*this),b) < 0;
	}

	bool in_seg (vec a, vec b) { return ccw(a,b) == 0 && dir(a,b) <= 0; } // tips included
	double dist2_lin (vec a, vec b) { return double(::sq(cross(a,b)))/a.sq(b); } // see cir.has_inter_lin
	double dist2_seg (vec a, vec b) { return a.dir((*this),b) == (b.dir((*this),a)) ? dist2_lin(a,b) : min(sq(a),sq(b)); }
};
struct lin { // line
	cood a, b, c; // a*x + b*y = c
	lin () {} lin (cood x, cood y, cood z) : a(x), b(y), c(z) {}
	lin (vec s, vec t) : a(t.y - s.y), b(s.x - t.x), c(a * s.x + b * s.y) {}
	inline lin parll (vec p) { return lin{a, b, a*p.x + b * p.y}; }
	inline lin perp () { return lin{-b, a, c}; }
	vec inter (lin o) {
		cood d = a * o.b - o.a * b;
		if (-eps <= d && d <= eps) throw 1; // parallel
		return vec((o.b * c - b * o.c) / d, (a * o.c - o.a * c) / d);
	}
	bool contains (vec v) { return abs(a*v.x + b*v.y - c) <= eps; }
	vec at_x (cood x) { return vec(x,(c-a*x)/b); }
	vec at_y (cood y) { return vec((c-b*y)/a,y); }
};
struct cir { // circle
	vec c; cood r;
	cir () {} cir (vec v, cood d) : c(v), r(d) {}
	cir (vec u, vec v, vec w) {
		vec mv = (u+v)/2; lin s(mv, mv+(v-u).rot90());
		vec mw = (u+w)/2; lin t(mw, mw+(w-u).rot90());
		c = s.inter(t); r = c.nr(u);
	}
	inline bool contains (vec w) { return c.sq(w) <= sq(r) + eps; } // border included
	inline bool has_inter (cir o) { return c.sq(o.c) <= sq(r + o.r) + eps; } // borders included
	inline bool has_border_inter (cir o) { return has_inter(o) && c.sq(o.c) + eps >= sq(r - o.r); }
	inline bool has_inter_lin (vec a, vec b) { return a.sq(b) <= eps ? contains(a) : sq(c.cross(a,b)) <= sq(r)*a.sq(b) + eps; } // borders included XXX overflow
	inline bool has_inter_seg (vec a, vec b) { return has_inter_lin(a,b) && (contains(a) || contains(b) || a.dir(c,b)*b.dir(c,a) != -1); } // borders and tips included XXX overflow
	inline double arc_area (vec a, vec b) { return c.angle(a,b)*r*r/2; } // smallest arc, ccw positive
	inline double arc_len (vec a, vec b) { return c.angle(a,b)*r; } // smallest arc, ccw positive
	pair<vec,vec> border_inter (cir o) {
		if (!has_border_inter(o)) throw 0;
		double a = (sq(r) + o.c.sq(c) - sq(o.r))/(2*o.c.nr(c));
		vec v = (o.c - c)/o.c.nr(c); vec m = c + v * a;
		double h = sqrt(sq(r) - sq(a)); h = h!=h?0:h;
		return pair<vec,vec>(m + v.rot90()*h, m - v.rot90()*h);
	}
	pair<vec,vec> border_inter_lin (vec a, vec b) { // first is closest to a than second
		if (a.dir(b,c) == -1) swap(a,b);
		if (!has_inter_lin(a,b)) throw 0;
		double d2 = c.dist2_lin(a,b); vec p = (b-a)/a.nr(b);
		double h = sqrt(r*r - d2); h = h!=h?0:h; 
		double y = sqrt(c.sq(a) - d2); y = y!=y?0:y;
		return pair<vec,vec>(a + p*(y-h), a + p*(y+h));
	}
	double triang_inter (vec a, vec b) { // ccw oriented, this with (c,a,b)
		if (c.sq(a) > c.sq(b)) return -triang_inter(b,a);
		if (contains(b)) return c.cross(a,b)/2;
		if (!has_inter_seg(a,b)) return arc_area(a,b);
		pair<vec,vec> itr = border_inter_lin(b,a); // order important
		if (contains(a)) return c.cross(a,itr.first)/2 + arc_area(itr.first,b);
		return arc_area(a,itr.second) + c.cross(itr.second,itr.first)/2 + arc_area(itr.first,b);
	}
};
bool inter_seg (vec a, vec b, vec c, vec d) {
	if (a.in_seg(c, d) || b.in_seg(c, d) || c.in_seg(a, b) || d.in_seg(a, b)) return true;
	return (c.ccw(a, b) * d.ccw(a, b) == -1 && a.ccw(c, d) * b.ccw(c, d) == -1);
}
double dist2_seg (vec a, vec b, vec c, vec d){return inter_seg(a,b,c,d)?0.:min({ a.dist2_seg(c,d), b.dist2_seg(c,d), c.dist2_seg(a,b), d.dist2_seg(a,b) });} // TODO
ostream& operator<<(ostream& os, vec o) { return os << '(' << o.x << ", " << o.y << ')'; }
ostream& operator<<(ostream& os, lin o) { return os << '[' << o.a << "x + " << o.b << "y = " << o.c << ']'; }
ostream& operator<<(ostream& os, cir o) { return os << '[' << o.c << o.r << ']'; }

double polygon_inter (vector<vec> & p, cir c) { // signed area
	return inner_product(p.begin(), p.end()-1, p.begin()+1, c.triang_inter(*p.rbegin(),*p.begin()), std::plus<double>(), [&c] (vec a, vec b) { return c.triang_inter(a,b); });
}

const int N = 13;

int n;
ll r;
vector<vec> v(N);

double solve (double y) {
	double lo = 100, hi = 0;
	for (int i = 0; i < n; i++) {
		if (abs(v[i].y - v[i+1].y) <= eps) {
			if (abs(v[i].y - y) <= eps) {
				lo = min(lo, v[i].x);
				lo = min(lo, v[i+1].x);
				hi = max(hi, v[i].x);
				hi = max(hi, v[i+1].x);
			}
		} else if (min(v[i].y,v[i+1].y) - eps <= y && y <= max(v[i].y,v[i+1].y) + eps) {
			double x = lin(v[i],v[i+1]).at_y(y).x;
			lo = min(lo, x);
			hi = max(hi, x);
		}
	}
	if (lo > hi) return 0;

	int ts = 70;
	while (ts--) {
		double q1 = (lo + lo + hi)/3;
		double q2 = (lo + hi + hi)/3;
		if (abs(polygon_inter(v, cir(vec(q1,y),r))) > abs(polygon_inter(v, cir(vec(q2,y),r))))
			hi = q2;
		else
			lo = q1;
	}
	
	//cout << lo << " " << y << " : " << abs(polygon_inter(v, cir(vec(lo,y),r))) << endl;
	return abs(polygon_inter(v, cir(vec(lo,y),r)));
}

int main () {
	while (scanf("%d %lld", &n, &r) != EOF) {
		double lo = 100, hi = 0;
		for (int i = 0; i < n; i++) {
			scanf("%lf %lf", &v[i].x, &v[i].y);
			lo = min(lo, v[i].y);
			hi = max(hi, v[i].y);
		}
		v[n] = v[0];

		int ts = 80;
		while (ts--) {
			double q1 = (lo + lo + hi)/3;
			double q2 = (lo + hi + hi)/3;

			if (solve(q1) < solve(q2))
				lo = q1;
			else
				hi = q2;
		}
		
		printf("%.6f\n", solve(lo));
	}
}
accuracy: 1
time_ms: 20
memory_kb: 3556
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define cout if (1) cout

// XXX without explanation marks untested functions

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

// NOT STANDART FROM HERE

// area de calota 2.pi.R.h (h altura)
// volume de calota pi.h/6 * (3r^2 + h^2)

 typedef double cood;
 cood eps = 1e-8;
// tests for double were made with eps = 1e-8

double eps_d = 1e-8; // necessary even in integer geometry, should be eps otherwise

const double pi = acos(-1.);

inline ll sq (ll x)
{ return x*x; }
inline double sq (double x)
{ return x*x; }

struct vec { // vector
	// === BASIC ===
	cood x, y;
	vec () : x(0), y(0) {}
	vec (cood a, cood b) : x(a), y(b) {}
	friend ostream& operator<<(ostream& os, vec o);

	vec operator - (vec o)
	{ return vec(x - o.x, y - o.y); }
	vec operator + (vec o)
	{ return vec(x + o.x, y + o.y); }
	vec operator * (cood o)
	{ return vec(x * o, y * o); }
	vec operator / (cood o)
	{ return vec(x / o, y / o); }
	cood operator ^ (vec o)
	{ return x * o.y - y * o.x; }
	cood operator * (vec o)
	{ return x * o.x + y * o.y; }

	// positive is (*this)b is clockwise from (*this)a
	double angle (vec a, vec b)
	{ return atan2((a-(*this))^(b-(*this)), (a-(*this))*(b-(*this))); }

	cood sq (vec o = vec())
	{ return ((*this)-o)*((*this)-o); }
	double nr (vec o = vec())
	{ return sqrt(sq(o)); }

	cood cross (vec a, vec b) // ccw signed area (positive if this is to the left of ab)
	{ return (b - a) ^ ((*this) - a); }
	int ccw (vec a, vec b) // which side is this from ab? (1 left, 0 over, -1 right)
	{ cood o = cross(a, b); return (eps < o) - (o < -eps); } 

	int dir (vec a, vec b) // direction of (this)a relative to (this)b (-1 opposite, 0 none, 1 same)
	{ cood o = ((*this) - a)*((*this) - b); return (eps < o) - (o < -eps); }

	cood inner (vec s, vec t) // (p-s)*(t-s) where p = this projected on st
	{ return ((*this) - s) * (t - s); }
	vec proj (vec s, vec t) // projection of this point over line st
	{ return s + (t - s)*(inner(s,t) / t.sq(s)); }

	vec rotate (double a) // rotate ccw by a (fails with ll)
	{ return vec(cos(a) * x - sin(a) * y, sin(a) * x + cos(a) * y); }
	vec rot90 () // rotate pi/2 ccw
	{ return vec(-y, x); }

	// === ADVANCED ===
	// ordering that defines the compare method
	// used only there, change it accordingly
	// sorts increasing on y and, then increasing on x
	bool operator < (const vec & o) const {
		if (y != o.y)
			return y < o.y;
		return x < o.x;
	}

	// full ordering (ccw angle from this+(1,0), distance to this)
	// is a < b?
	// PRECISION : ok with double if norm in [-1e9,5e3]
	bool compare (vec a, vec b) {
		if (((*this) < a) != ((*this) < b))
			return (*this) < a;
		int o = ccw(a,b);
		if (o) return o > 0;
		return a.dir((*this),b) < 0;
	}

	// is this inside segment st? (tip of segment included, change for dr < 0 otherwise)
	bool in_seg (vec s, vec t)
	{ return (ccw(s,t) == 0) && (dir(s,t) <= 0); }

	// squared distance from this to line defined by st
	double dist2_lin (vec s, vec t)
	{ return double(::sq(cross(s,t))) / t.sq(s); }
	// squared distance from this to segment st
	double dist2_seg (vec s, vec t) 
	{ return s.dir((*this),t) == t.dir((*this),s) ? dist2_lin(s,t) : min(sq(s),sq(t)); }

	// is this inside (borders included) the convex polygon v of size n?
	// if yes, prec is the vec that this on acw order from v[0] or 0 if there is no such
	// if not, prec is the predecessor of this when added to poly and succ is the sucessor
	// p should be a vector with [0..n-1]
	// n should be >= 2
	bool in_conv_poly (vec v[], int n, const vector<int> & p, int & prec, int & succ) {
		if (nr(v[0]) <= eps) {
			prec = 0;
			return 1;
		}

		if (n == 2) {
			if (in_seg(v[0],v[1]))
				return (prec = 1);

			if (ccw(v[0],v[1]) > 0) {
				prec = 1;
				succ = 0;
			} else if (ccw(v[0],v[1]) < 0) {
				prec = 0;
				succ = 1;
			} else {
				prec = succ = (v[0].dir((*this),v[1]) < 0);
			}
			return 0;
		}
		
		if (ccw(v[0],v[1]) > 0 || ccw(v[0],v[n-1]) < 0) {
		// case where v[0] is not removed
			// last diagonal before or over this
			int di = lower_bound(p.begin() + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) >= 0;
			}) - p.begin() - 1;

			// is this inside the polygon?
			prec = di;
			if (di == n-1) {
			// last segment
				if (ccw(v[0],v[n-1]) == 0 && ccw(v[n-2],v[n-1]) >= 0)
					return 1;
			} else {
			// inside otherwise
				if (ccw(v[di],v[di+1]) >= 0)
					return 1;
			}

			// last that stays before (or eq to) di
			prec = lower_bound(p.begin() + 1, p.begin() + di + 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;

			// first that stays after di
			succ = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v,n] (int i, int j) {
				assert(j == -1);
				return ccw(v[(i+1)%n],v[i]) >= 0;
			}) - p.begin();
			if (succ == n) succ = 0;
		} else {
		// case where v[0] is removed
			// first diagonal before of over this
			// di is certainly not removed
			int di = lower_bound(p.begin() + 1, p.end() - 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) < 0;
			}) - p.begin();

			// first that stays (<= di)
			succ = lower_bound(p.begin(), p.begin() + di, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i+1],v[i]) >= 0;
			}) - p.begin();

			// last that stays (>= di)
			prec = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;
		}
		return 0;
	}
};
ostream& operator<<(ostream& os, vec o)
{ return os << '(' << o.x << ", " << o.y << ')'; }

struct lin { // line
	cood a, b, c; // a*x + b*y = c

	lin () {}
	lin (cood x, cood y, cood z) : a(x), b(y), c(z) {}
	lin (vec s, vec t) : a(t.y - s.y), b(s.x - t.x), c(a * s.x + b * s.y) {}

	lin parll (vec p) // parallel to this through p
	{ return lin(a, b, a * p.x + b * p.y); }
	lin perp ()
	{ return lin(-b, a, c); }

	vec inter (lin o) {
		cood d = a * o.b - o.a * b;
		if (d < eps && -eps < d) throw 0; // parallel
		return vec((o.b * c - b * o.c) / d, (a * o.c - o.a * c) / d);
	}
};

struct cir { // circle
	vec c; cood r;

	// borders included
	bool contains (vec w)
	{ return c.sq(w) <= sq(r) + eps; }
	bool has_inter (cir o)
	{ return c.sq(o.c) <= sq(r + o.r) + eps; }
	bool has_inter_lin (vec s, vec t)
	{ return c.dist2_lin(s,t) <= sq(r) + eps_d; }
	bool has_inter_seg (vec s, vec t)
	{ return c.dist2_seg(s,t) <= sq(r) + eps_d; }

	// borders not included
	bool contains (cir o)
	{ return (o.r < r - eps && c.sq(o.c) < sq(r - o.r) - eps); }

	// ccw area of arc from ca to cb
	double arc_area (vec a, vec b) {
		double ang = c.angle(a,b);
		return r*r*ang*.5;
	}

	// double only
	pair<vec,vec> inter_pts (cir o) {
		assert(has_inter(o) && !contains(o)); // fully contained case
		double d = c.nr(o.c);
		double a = (r*r + d*d - o.r*o.r) / (2.*d); // r*cos(ans,v,c.v)
		double h = sqrt(r*r - a*a);
		if (h != h) h = 0;
		vec p = o.c - c;
		return pair<vec,vec>(c + p*(a/d) + (p.rot90()*(h/d)), c + p*(a/d) - (p.rot90()*(h/d)));
	}

	// double only XXX careful precision
	pair<vec,vec> inter_pts (vec s, vec t) { 
		assert(has_inter_lin(s,t));
		double h2 = c.dist2_lin(s,t);
		double d = sqrt(c.sq(t) - h2);
		if (d != d) d = 0;
		vec p = (s-t);
		vec m = t + p*(d/p.nr());
		vec m_b = t - p*(d/p.nr());
		if (m_b.sq(c) < m.sq(c))
			m = m_b;

		d = sqrt(r*r - h2);
		if (d != d) d = 0;
		return pair<vec,vec>(m + p*(d/p.nr()), m - p*(d/p.nr()));
	}

	// double only XXX not tested
	// signed area of intersection of this with triangle (this.c,a,b)
	double inter (vec a, vec b) {
		double res = 0.; bool inv = 0;
		if (contains(b)) {
			swap(a,b);
			inv = 1;
		}

		if (contains(b)) {
			res = c.cross(a,b)*.5;
		} else if (contains(a)) {
			pair<vec,vec> rt = inter_pts(a,b);
			vec q = rt.first;
			if (!q.in_seg(a,b) || (a.sq(q) <= eps && rt.second.in_seg(a,b)))
				q = rt.second;
			res += c.cross(a,q)*.5;
			res += arc_area(q,b);
		} else if (has_inter_seg(a,b)) {
			pair<vec,vec> rt = inter_pts(a,b);
			if (a.sq(rt.second) < a.sq(rt.first))
				swap(rt.first,rt.second);
			res += arc_area(a,rt.first);
			res += c.cross(rt.first,rt.second)*.5;
			res += arc_area(rt.second,b);
		} else {
			res += arc_area(a,b);
		}

		if (inv) return -res;
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with polygon
	double inter (vector<vec> & p) {
		double res = 0;
		for (int i = 0; i < p.size(); i++)
			res += inter(p[i],p[(i+1)%p.size()]);
		return res;
	}
};

// do the segments ab and cd intersect? (borders included) XXX
bool inter_seg (vec a, vec b, vec c, vec d) {
	if (a.in_seg(c, d) || b.in_seg(c, d) || c.in_seg(a, b) || d.in_seg(a, b))
		return true;
	return (c.ccw(a, b) * d.ccw(a, b) == -1 && a.ccw(c, d) * b.ccw(c, d) == -1);
}

// squared distance from segments ab and cd XXX
double dist2_seg (vec a, vec b, vec c, vec d)
{ return inter_seg(a,b,c,d) ? 0. : min({ a.dist2_seg(c,d), b.dist2_seg(c,d), c.dist2_seg(a,b), d.dist2_seg(a,b) }); }

// brd = do points on the border belong to convex?
// computes convex hull of given vector (inplace)
// returns size of convex hull
int graham (vec v[], int n, int brd) {
	for (int i = 1; i < n; i++) {
		if (v[i].x < v[0].x || (v[i].x == v[0].x && v[i].y < v[0].y))
			swap(v[0], v[i]);
	}

	sort(v+1, v+n, [v] (vec a, vec b) {
		int o = b.ccw(v[0], a);
		if (o) return (o == 1);
		return v[0].sq(a) < v[0].sq(b);
	});

	if (brd) {
		int s = n-1;
		while (s > 1 && v[s].ccw(v[s-1],v[0]) == 0)
			s--;
		for (int i = s; i < n - 1 - (i - s); i++)
			swap(v[i], v[n-1-(i-s)]);
	}

	int s = 0;
	for (int i = 0; i < n; i++) {
		if (s && v[s-1].x == v[i].x && v[s-1].y == v[i].y) continue;
		while (s >= 2 && v[s-1].ccw(v[s-2],v[i]) >= brd)
			s--;
		v[s++] = v[i];
	}

	return s;
}

const int N = 1e2+7;

int n;
double r;
vector<vec> v;
double x[2], y[2];

double solve (double x) {
	double lo = 200, hi = -100.;
	for (int i = 0; i < n; i++) {
		int j = (i+1)%n;
		lin ln(v[i],v[j]);
		vec it(x, (ln.c - ln.a*x)/ln.b);
		if (it.in_seg(v[i],v[j]) && it.y == it.y && abs(it.y) < 200) {
			lo = min(lo, it.y);
			hi = max(hi, it.y);
		}

		if (abs(v[i].x - x) <= eps_d) {
			lo = min(lo, v[i].y);
			hi = max(hi, v[i].y);
		}
	}
	hi = min(hi, 200.); lo = max(lo, -100.);

	int ts = 60;
	while (ts--) {
		double q1 = (lo+lo+hi)/3;
		double q2 = (lo+hi+hi)/3;

		double r1 = abs(cir({ vec(x,q1), r }).inter(v));
		double r2 = abs(cir({ vec(x,q2), r }).inter(v));

		if (r1 < r2)
			lo = q1;
		else
			hi = q2;
	}

	return abs(cir({ vec(x,lo), r }).inter(v));
}

int main () {

	while (scanf("%d %lf", &n, &r) != EOF) {
		v = vector<vec>(n);
		
		x[0] = 200;
		x[1] = -100;

		for (int i = 0; i < n; i++) {
			scanf("%lf %lf", &v[i].x, &v[i].y);

			x[0] = min(x[0],v[i].x);
			x[1] = max(x[1],v[i].x);
		}

		double lo = x[0], hi = x[1];
		//int ts = 60;
		int ts = 50;
		while (ts--) {
			double q1 = (lo+lo+hi)/3;
			double q2 = (lo+hi+hi)/3;
			
			if (solve(q1) < solve(q2))
				lo = q1;
			else
				hi = q2;
		}

		double res = solve(lo);
		for (int i = 0; i < n; i++)
			res = max(res, abs(cir({ v[i], r }).inter(v)));

		printf("%.20f\n", res);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3528
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define cout if (0) cout

// XXX without explanation marks untested functions

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

// NOT STANDART FROM HERE

// area de calota 2.pi.R.h (h altura)
// volume de calota pi.h/6 * (3r^2 + h^2)

 typedef double cood;
 cood eps = 1e-8;
// tests for double were made with eps = 1e-8

double eps_d = 1e-8; // necessary even in integer geometry, should be eps otherwise

const double pi = acos(-1.);

inline ll sq (ll x)
{ return x*x; }
inline double sq (double x)
{ return x*x; }

struct vec { // vector
	// === BASIC ===
	cood x, y;
	vec () : x(0), y(0) {}
	vec (cood a, cood b) : x(a), y(b) {}
	friend ostream& operator<<(ostream& os, vec o);

	vec operator - (vec o)
	{ return vec(x - o.x, y - o.y); }
	vec operator + (vec o)
	{ return vec(x + o.x, y + o.y); }
	vec operator * (cood o)
	{ return vec(x * o, y * o); }
	vec operator / (cood o)
	{ return vec(x / o, y / o); }
	cood operator ^ (vec o)
	{ return x * o.y - y * o.x; }
	cood operator * (vec o)
	{ return x * o.x + y * o.y; }

	// positive is (*this)b is clockwise from (*this)a
	double angle (vec a, vec b)
	{ return atan2((a-(*this))^(b-(*this)), (a-(*this))*(b-(*this))); }

	cood sq (vec o = vec())
	{ return ((*this)-o)*((*this)-o); }
	double nr (vec o = vec())
	{ return sqrt(sq(o)); }

	cood cross (vec a, vec b) // ccw signed area (positive if this is to the left of ab)
	{ return (b - a) ^ ((*this) - a); }
	int ccw (vec a, vec b) // which side is this from ab? (1 left, 0 over, -1 right)
	{ cood o = cross(a, b); return (eps < o) - (o < -eps); } 

	int dir (vec a, vec b) // direction of (this)a relative to (this)b (-1 opposite, 0 none, 1 same)
	{ cood o = ((*this) - a)*((*this) - b); return (eps < o) - (o < -eps); }

	cood inner (vec s, vec t) // (p-s)*(t-s) where p = this projected on st
	{ return ((*this) - s) * (t - s); }
	vec proj (vec s, vec t) // projection of this point over line st
	{ return s + (t - s)*(inner(s,t) / t.sq(s)); }

	vec rotate (double a) // rotate ccw by a (fails with ll)
	{ return vec(cos(a) * x - sin(a) * y, sin(a) * x + cos(a) * y); }
	vec rot90 () // rotate pi/2 ccw
	{ return vec(-y, x); }

	// === ADVANCED ===
	// ordering that defines the compare method
	// used only there, change it accordingly
	// sorts increasing on y and, then increasing on x
	bool operator < (const vec & o) const {
		if (y != o.y)
			return y < o.y;
		return x < o.x;
	}

	// full ordering (ccw angle from this+(1,0), distance to this)
	// is a < b?
	// PRECISION : ok with double if norm in [-1e9,5e3]
	bool compare (vec a, vec b) {
		if (((*this) < a) != ((*this) < b))
			return (*this) < a;
		int o = ccw(a,b);
		if (o) return o > 0;
		return a.dir((*this),b) < 0;
	}

	// is this inside segment st? (tip of segment included, change for dr < 0 otherwise)
	bool in_seg (vec s, vec t)
	{ return (ccw(s,t) == 0) && (dir(s,t) <= 0); }

	// squared distance from this to line defined by st
	double dist2_lin (vec s, vec t)
	{ return double(::sq(cross(s,t))) / t.sq(s); }
	// squared distance from this to segment st
	double dist2_seg (vec s, vec t) 
	{ return s.dir((*this),t) == t.dir((*this),s) ? dist2_lin(s,t) : min(sq(s),sq(t)); }

	// is this inside (borders included) the convex polygon v of size n?
	// if yes, prec is the vec that this on acw order from v[0] or 0 if there is no such
	// if not, prec is the predecessor of this when added to poly and succ is the sucessor
	// p should be a vector with [0..n-1]
	// n should be >= 2
	bool in_conv_poly (vec v[], int n, const vector<int> & p, int & prec, int & succ) {
		if (nr(v[0]) <= eps) {
			prec = 0;
			return 1;
		}

		if (n == 2) {
			if (in_seg(v[0],v[1]))
				return (prec = 1);

			if (ccw(v[0],v[1]) > 0) {
				prec = 1;
				succ = 0;
			} else if (ccw(v[0],v[1]) < 0) {
				prec = 0;
				succ = 1;
			} else {
				prec = succ = (v[0].dir((*this),v[1]) < 0);
			}
			return 0;
		}
		
		if (ccw(v[0],v[1]) > 0 || ccw(v[0],v[n-1]) < 0) {
		// case where v[0] is not removed
			// last diagonal before or over this
			int di = lower_bound(p.begin() + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) >= 0;
			}) - p.begin() - 1;

			// is this inside the polygon?
			prec = di;
			if (di == n-1) {
			// last segment
				if (ccw(v[0],v[n-1]) == 0 && ccw(v[n-2],v[n-1]) >= 0)
					return 1;
			} else {
			// inside otherwise
				if (ccw(v[di],v[di+1]) >= 0)
					return 1;
			}

			// last that stays before (or eq to) di
			prec = lower_bound(p.begin() + 1, p.begin() + di + 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;

			// first that stays after di
			succ = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v,n] (int i, int j) {
				assert(j == -1);
				return ccw(v[(i+1)%n],v[i]) >= 0;
			}) - p.begin();
			if (succ == n) succ = 0;
		} else {
		// case where v[0] is removed
			// first diagonal before of over this
			// di is certainly not removed
			int di = lower_bound(p.begin() + 1, p.end() - 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) < 0;
			}) - p.begin();

			// first that stays (<= di)
			succ = lower_bound(p.begin(), p.begin() + di, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i+1],v[i]) >= 0;
			}) - p.begin();

			// last that stays (>= di)
			prec = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;
		}
		return 0;
	}
};
ostream& operator<<(ostream& os, vec o)
{ return os << '(' << o.x << ", " << o.y << ')'; }

struct lin { // line
	cood a, b, c; // a*x + b*y = c

	lin () {}
	lin (cood x, cood y, cood z) : a(x), b(y), c(z) {}
	lin (vec s, vec t) : a(t.y - s.y), b(s.x - t.x), c(a * s.x + b * s.y) {}

	lin parll (vec p) // parallel to this through p
	{ return lin(a, b, a * p.x + b * p.y); }
	lin perp ()
	{ return lin(-b, a, c); }

	vec inter (lin o) {
		cood d = a * o.b - o.a * b;
		if (d < eps && -eps < d) throw 0; // parallel
		return vec((o.b * c - b * o.c) / d, (a * o.c - o.a * c) / d);
	}
};

struct cir { // circle
	vec c; cood r;

	// borders included
	bool contains (vec w)
	{ return c.sq(w) <= sq(r) + eps; }
	bool has_inter (cir o)
	{ return c.sq(o.c) <= sq(r + o.r) + eps; }
	bool has_inter_lin (vec s, vec t)
	{ return c.dist2_lin(s,t) <= sq(r) + eps_d; }
	bool has_inter_seg (vec s, vec t)
	{ return c.dist2_seg(s,t) <= sq(r); }

	// borders not included
	bool contains (cir o)
	{ return (o.r < r - eps && c.sq(o.c) < sq(r - o.r) - eps); }

	// ccw oriented area of arc from a to b
	double arc_area (vec a, vec b) {
		double ang = c.angle(a,b);
		return r*r*ang*.5;
	}

	// double only
	pair<vec,vec> inter_pts (cir o) {
		assert(has_inter(o) && !contains(o)); // fully contained case
		double d = c.nr(o.c);
		double a = (r*r + d*d - o.r*o.r) / (2.*d); // r*cos(ans,v,c.v)
		double h = sqrt(r*r - a*a);
		if (h != h) h = 0;
		vec p = o.c - c;
		return pair<vec,vec>(c + p*(a/d) + (p.rot90()*(h/d)), c + p*(a/d) - (p.rot90()*(h/d)));
	}

	// double only XXX careful precision
	pair<vec,vec> inter_pts (vec s, vec t) { 
		assert(has_inter_lin(s,t));
		double h2 = c.dist2_lin(s,t);
		double d = sqrt(c.sq(t) - h2);
		if (d != d) d = 0;
		vec p = (s-t);
		vec m = t + p*(d/p.nr());
		vec m_b = t - p*(d/p.nr());
		if (m_b.sq(c) < m.sq(c))
			m = m_b;

		d = sqrt(r*r - h2);
		if (d != d) d = 0;
		pair<vec,vec> res(m + p*(d/p.nr()), m - p*(d/p.nr()));
		if (res.first.sq(t) > res.second.sq(t))
			swap(res.first, res.second);
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with triangle (this.c,a,b)
	double inter (vec a, vec b) {
		cout << c << " with " << a << "," << b << ": ";
		double res = 0.;
		bool inv = 0;
		if (contains(b)) {
			swap(a,b);
			inv = 1;
			cout << "[inv] ";
		}

		if (contains(b)) {
			cout << "contains both";
			res = c.cross(a,b)*.5;
		} else if (contains(a)) {
			cout << "contains " << a;
			pair<vec,vec> rt = inter_pts(a,b);
			cout << endl << "[[" << rt.first << " " << rt.second << endl;
			vec q = rt.first;
			if (!q.in_seg(a,b) || (a.sq(q) <= eps && rt.second.in_seg(a,b)))
			//if (rt.second.dist2_seg(a,b) < q.dist2_seg(a,b))
				q = rt.second;
			cout << " inter at " << q;

			res += c.cross(a,q)*.5;
			res += arc_area(q,b);
		} else if (has_inter_seg(a, b)) {
			cout << "inter seg";
			pair<vec,vec> rt = inter_pts(b,a);

			res += arc_area(a,rt.first);
			res += c.cross(rt.first,rt.second)*.5;
			res += arc_area(rt.second,b);
		} else {
			cout << "arc only";
			res += arc_area(a,b);
		}

		if (inv) res = -res;
		cout << " = " << res << endl;
		return res;
	}

	double area (vec a, vec b) {
		double aa = c.nr(a), bb = c.nr(b), cc = sqrt(c.dist2_seg(a,b));
		if (aa <= r + eps && bb <= r + eps) return .5*abs((a-c)^(b-c));
		if (cc >= r - eps) return .5*abs(r*r*c.angle(a,b));

		if (aa > bb + eps) { swap(a,b); swap(aa,bb); }
		double A = a.sq(b), B = 2.*((a-b)*(b-c)), C = b.sq(c) - r*r;
		double t = B*B-4*A*C;
		if (abs(t) <= eps) t = 0;
		else t = sqrt(t);
		double x1 = .5*(-B-t)/A, x2 = .5*(-B+t)/A;
		vec p1 = a*x1 + b*(1-x1), p2 = a*x2 + b*(1-x2);

		if (aa < r - eps) return area(a,p1) + area(p1,b);
		return area(a,p2) + area(p2,p1) + area(p1,b);
	}

	// double only XXX not tested
	// signed area of intersection of this with polygon
	double inter (vector<vec> & p) {
		double res = 0;
		for (int i = 0; i < p.size(); i++) {
			//res += area(p[i],p[(i+1)%p.size()]) * c.ccw(p[i],p[(i+1)%p.size()]);
			res += inter(p[i],p[(i+1)%p.size()]);
		}

		return res;
	}
};

// do the segments ab and cd intersect? (borders included) XXX
bool inter_seg (vec a, vec b, vec c, vec d) {
	if (a.in_seg(c, d) || b.in_seg(c, d) || c.in_seg(a, b) || d.in_seg(a, b))
		return true;
	return (c.ccw(a, b) * d.ccw(a, b) == -1 && a.ccw(c, d) * b.ccw(c, d) == -1);
}

// squared distance from segments ab and cd XXX
double dist2_seg (vec a, vec b, vec c, vec d)
{ return inter_seg(a,b,c,d) ? 0. : min({ a.dist2_seg(c,d), b.dist2_seg(c,d), c.dist2_seg(a,b), d.dist2_seg(a,b) }); }

// brd = do points on the border belong to convex?
// computes convex hull of given vector (inplace)
// returns size of convex hull
int graham (vec v[], int n, int brd) {
	for (int i = 1; i < n; i++) {
		if (v[i].x < v[0].x || (v[i].x == v[0].x && v[i].y < v[0].y))
			swap(v[0], v[i]);
	}

	sort(v+1, v+n, [v] (vec a, vec b) {
		int o = b.ccw(v[0], a);
		if (o) return (o == 1);
		return v[0].sq(a) < v[0].sq(b);
	});

	if (brd) {
		int s = n-1;
		while (s > 1 && v[s].ccw(v[s-1],v[0]) == 0)
			s--;
		for (int i = s; i < n - 1 - (i - s); i++)
			swap(v[i], v[n-1-(i-s)]);
	}

	int s = 0;
	for (int i = 0; i < n; i++) {
		if (s && v[s-1].x == v[i].x && v[s-1].y == v[i].y) continue;
		while (s >= 2 && v[s-1].ccw(v[s-2],v[i]) >= brd)
			s--;
		v[s++] = v[i];
	}

	return s;
}

const int N = 1e2+7;

int n;
double r;
vector<vec> v;
double x[2], y[2];

double solve (double x) {
	double lo = 200, hi = -100.;
	for (int i = 0; i < n; i++) {
		int j = (i+1)%n;
		lin ln(v[i],v[j]);
		vec it(x, (ln.c - ln.a*x)/ln.b);
		cout << it << " ";
		if (it.in_seg(v[i],v[j]) && it.y == it.y && abs(it.y) < 200) {
			lo = min(lo, it.y);
			hi = max(hi, it.y);
		}

		if (abs(v[i].x - x) <= eps_d) {
			cout << v[i] << "! ";
			lo = min(lo, v[i].y);
			hi = max(hi, v[i].y);
		}
	}
	hi = min(hi, 200.); lo = max(lo, -100.);
	cout << x << " [" << lo << " " << hi << "]" << endl;

	int ts = 60;
	while (ts--) {
		double q1 = (lo+lo+hi)/3;
		double q2 = (lo+hi+hi)/3;

		double r1 = abs(cir({ vec(x,q1), r }).inter(v));
		double r2 = abs(cir({ vec(x,q2), r }).inter(v));

		if (r1 < r2)
			lo = q1;
		else
			hi = q2;
	}

	return abs(cir({ vec(x,lo), r }).inter(v));
}

int main () {

	while (scanf("%d %lf", &n, &r) != EOF) {
		cout << n << endl;
		v = vector<vec>(n);
		
		x[0] = 200;
		x[1] = -100;

		for (int i = 0; i < n; i++) {
			scanf("%lf %lf", &v[i].x, &v[i].y);
			cout << v[i] << " ";

			x[0] = min(x[0],v[i].x);
			x[1] = max(x[1],v[i].x);
		}
		cout << endl;

		double lo = x[0], hi = x[1];
		//int ts = 60;
		int ts = 50;
		while (ts--) {
			double q1 = (lo+lo+hi)/3;
			double q2 = (lo+hi+hi)/3;
			
			if (solve(q1) < solve(q2))
				lo = q1;
			else
				hi = q2;
		}

		double res = solve(lo);
		for (int i = 0; i < n; i++)
			res = max(res, abs(cir({ v[i], r }).inter(v)));

		printf("%.20f\n", res);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3532
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define cout if (0) cout

// XXX without explanation marks untested functions

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

// NOT STANDART FROM HERE

// area de calota 2.pi.R.h (h altura)
// volume de calota pi.h/6 * (3r^2 + h^2)

 typedef double cood;
 cood eps = 1e-8;
// tests for double were made with eps = 1e-8

double eps_d = 1e-8; // necessary even in integer geometry, should be eps otherwise

const double pi = acos(-1.);

inline ll sq (ll x)
{ return x*x; }
inline double sq (double x)
{ return x*x; }

struct vec { // vector
	// === BASIC ===
	cood x, y;
	vec () : x(0), y(0) {}
	vec (cood a, cood b) : x(a), y(b) {}
	friend ostream& operator<<(ostream& os, vec o);

	vec operator - (vec o)
	{ return vec(x - o.x, y - o.y); }
	vec operator + (vec o)
	{ return vec(x + o.x, y + o.y); }
	vec operator * (cood o)
	{ return vec(x * o, y * o); }
	vec operator / (cood o)
	{ return vec(x / o, y / o); }
	cood operator ^ (vec o)
	{ return x * o.y - y * o.x; }
	cood operator * (vec o)
	{ return x * o.x + y * o.y; }

	// positive is (*this)b is clockwise from (*this)a
	double angle (vec a, vec b)
	{ return atan2((a-(*this))^(b-(*this)), (a-(*this))*(b-(*this))); }

	cood sq (vec o = vec())
	{ return ((*this)-o)*((*this)-o); }
	double nr (vec o = vec())
	{ return sqrt(sq(o)); }

	cood cross (vec a, vec b) // ccw signed area (positive if this is to the left of ab)
	{ return (b - a) ^ ((*this) - a); }
	int ccw (vec a, vec b) // which side is this from ab? (1 left, 0 over, -1 right)
	{ cood o = cross(a, b); return (eps < o) - (o < -eps); } 

	int dir (vec a, vec b) // direction of (this)a relative to (this)b (-1 opposite, 0 none, 1 same)
	{ cood o = ((*this) - a)*((*this) - b); return (eps < o) - (o < -eps); }

	cood inner (vec s, vec t) // (p-s)*(t-s) where p = this projected on st
	{ return ((*this) - s) * (t - s); }
	vec proj (vec s, vec t) // projection of this point over line st
	{ return s + (t - s)*(inner(s,t) / t.sq(s)); }

	vec rotate (double a) // rotate ccw by a (fails with ll)
	{ return vec(cos(a) * x - sin(a) * y, sin(a) * x + cos(a) * y); }
	vec rot90 () // rotate pi/2 ccw
	{ return vec(-y, x); }

	// === ADVANCED ===
	// ordering that defines the compare method
	// used only there, change it accordingly
	// sorts increasing on y and, then increasing on x
	bool operator < (const vec & o) const {
		if (y != o.y)
			return y < o.y;
		return x < o.x;
	}

	// full ordering (ccw angle from this+(1,0), distance to this)
	// is a < b?
	// PRECISION : ok with double if norm in [-1e9,5e3]
	bool compare (vec a, vec b) {
		if (((*this) < a) != ((*this) < b))
			return (*this) < a;
		int o = ccw(a,b);
		if (o) return o > 0;
		return a.dir((*this),b) < 0;
	}

	// is this inside segment st? (tip of segment included, change for dr < 0 otherwise)
	bool in_seg (vec s, vec t)
	{ return (ccw(s,t) == 0) && (dir(s,t) <= 0); }

	// squared distance from this to line defined by st
	double dist2_lin (vec s, vec t)
	{ return double(::sq(cross(s,t))) / t.sq(s); }
	// squared distance from this to segment st
	double dist2_seg (vec s, vec t) 
	{ return s.dir((*this),t) == t.dir((*this),s) ? dist2_lin(s,t) : min(sq(s),sq(t)); }

	// is this inside (borders included) the convex polygon v of size n?
	// if yes, prec is the vec that this on acw order from v[0] or 0 if there is no such
	// if not, prec is the predecessor of this when added to poly and succ is the sucessor
	// p should be a vector with [0..n-1]
	// n should be >= 2
	bool in_conv_poly (vec v[], int n, const vector<int> & p, int & prec, int & succ) {
		if (nr(v[0]) <= eps) {
			prec = 0;
			return 1;
		}

		if (n == 2) {
			if (in_seg(v[0],v[1]))
				return (prec = 1);

			if (ccw(v[0],v[1]) > 0) {
				prec = 1;
				succ = 0;
			} else if (ccw(v[0],v[1]) < 0) {
				prec = 0;
				succ = 1;
			} else {
				prec = succ = (v[0].dir((*this),v[1]) < 0);
			}
			return 0;
		}
		
		if (ccw(v[0],v[1]) > 0 || ccw(v[0],v[n-1]) < 0) {
		// case where v[0] is not removed
			// last diagonal before or over this
			int di = lower_bound(p.begin() + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) >= 0;
			}) - p.begin() - 1;

			// is this inside the polygon?
			prec = di;
			if (di == n-1) {
			// last segment
				if (ccw(v[0],v[n-1]) == 0 && ccw(v[n-2],v[n-1]) >= 0)
					return 1;
			} else {
			// inside otherwise
				if (ccw(v[di],v[di+1]) >= 0)
					return 1;
			}

			// last that stays before (or eq to) di
			prec = lower_bound(p.begin() + 1, p.begin() + di + 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;

			// first that stays after di
			succ = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v,n] (int i, int j) {
				assert(j == -1);
				return ccw(v[(i+1)%n],v[i]) >= 0;
			}) - p.begin();
			if (succ == n) succ = 0;
		} else {
		// case where v[0] is removed
			// first diagonal before of over this
			// di is certainly not removed
			int di = lower_bound(p.begin() + 1, p.end() - 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) < 0;
			}) - p.begin();

			// first that stays (<= di)
			succ = lower_bound(p.begin(), p.begin() + di, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i+1],v[i]) >= 0;
			}) - p.begin();

			// last that stays (>= di)
			prec = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;
		}
		return 0;
	}
};
ostream& operator<<(ostream& os, vec o)
{ return os << '(' << o.x << ", " << o.y << ')'; }

struct lin { // line
	cood a, b, c; // a*x + b*y = c

	lin () {}
	lin (cood x, cood y, cood z) : a(x), b(y), c(z) {}
	lin (vec s, vec t) : a(t.y - s.y), b(s.x - t.x), c(a * s.x + b * s.y) {}

	lin parll (vec p) // parallel to this through p
	{ return lin(a, b, a * p.x + b * p.y); }
	lin perp ()
	{ return lin(-b, a, c); }

	vec inter (lin o) {
		cood d = a * o.b - o.a * b;
		if (d < eps && -eps < d) throw 0; // parallel
		return vec((o.b * c - b * o.c) / d, (a * o.c - o.a * c) / d);
	}
};

struct cir { // circle
	vec c; cood r;

	// borders included
	bool contains (vec w)
	{ return c.sq(w) <= sq(r) + eps; }
	bool has_inter (cir o)
	{ return c.sq(o.c) <= sq(r + o.r) + eps; }
	bool has_inter_lin (vec s, vec t)
	{ return c.dist2_lin(s,t) <= sq(r) + eps_d; }
	bool has_inter_seg (vec s, vec t)
	{ return c.dist2_seg(s,t) <= sq(r); }

	// borders not included
	bool contains (cir o)
	{ return (o.r < r - eps && c.sq(o.c) < sq(r - o.r) - eps); }

	// ccw oriented area of arc from a to b
	double arc_area (vec a, vec b) {
		double ang = c.angle(a,b);
		return r*r*ang*.5;
	}

	// double only
	pair<vec,vec> inter_pts (cir o) {
		assert(has_inter(o) && !contains(o)); // fully contained case
		double d = c.nr(o.c);
		double a = (r*r + d*d - o.r*o.r) / (2.*d); // r*cos(ans,v,c.v)
		double h = sqrt(r*r - a*a);
		if (h != h) h = 0;
		vec p = o.c - c;
		return pair<vec,vec>(c + p*(a/d) + (p.rot90()*(h/d)), c + p*(a/d) - (p.rot90()*(h/d)));
	}

	// double only XXX careful precision
	pair<vec,vec> inter_pts (vec s, vec t) { 
		assert(has_inter_lin(s,t));
		double h2 = c.dist2_lin(s,t);
		double d = sqrt(c.sq(t) - h2);
		if (d != d) d = 0;
		vec p = (s-t);
		vec m = t + p*(d/p.nr());
		vec m_b = t - p*(d/p.nr());
		if (m_b.sq(c) < m.sq(c))
			m = m_b;

		d = sqrt(r*r - h2);
		if (d != d) d = 0;
		pair<vec,vec> res(m + p*(d/p.nr()), m - p*(d/p.nr()));
		if (res.first.sq(t) > res.second.sq(t))
			swap(res.first, res.second);
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with triangle (this.c,a,b)
	double inter (vec a, vec b) {
		cout << c << " with " << a << "," << b << ": ";
		double res = 0.;
		bool inv = 0;
		if (contains(b)) {
			swap(a,b);
			inv = 1;
			cout << "[inv] ";
		}

		if (contains(b)) {
			cout << "contains both";
			res = c.cross(a,b)*.5;
		} else if (contains(a)) {
			cout << "contains " << a;
			pair<vec,vec> rt = inter_pts(a,b);
			cout << endl << "[[" << rt.first << " " << rt.second << endl;
			vec q = rt.first;
			if (!q.in_seg(a,b) || (a.sq(q) <= eps && rt.second.in_seg(a,b)))
			//if (rt.second.dist2_seg(a,b) < q.dist2_seg(a,b))
				q = rt.second;
			cout << " inter at " << q;

			res += c.cross(a,q)*.5;
			res += arc_area(q,b);
		} else if (has_inter_seg(a, b)) {
			cout << "inter seg";
			pair<vec,vec> rt = inter_pts(b,a);

			res += arc_area(a,rt.first);
			res += c.cross(rt.first,rt.second)*.5;
			res += arc_area(rt.second,b);
		} else {
			cout << "arc only";
			res += arc_area(a,b);
		}

		if (inv) res = -res;
		cout << " = " << res << endl;
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with polygon
	double inter (vector<vec> & p) {
		double res = 0;
		for (int i = 0; i < p.size(); i++)
			res += inter(p[i],p[(i+1)%p.size()]);
		return res;
	}
};

// do the segments ab and cd intersect? (borders included) XXX
bool inter_seg (vec a, vec b, vec c, vec d) {
	if (a.in_seg(c, d) || b.in_seg(c, d) || c.in_seg(a, b) || d.in_seg(a, b))
		return true;
	return (c.ccw(a, b) * d.ccw(a, b) == -1 && a.ccw(c, d) * b.ccw(c, d) == -1);
}

// squared distance from segments ab and cd XXX
double dist2_seg (vec a, vec b, vec c, vec d)
{ return inter_seg(a,b,c,d) ? 0. : min({ a.dist2_seg(c,d), b.dist2_seg(c,d), c.dist2_seg(a,b), d.dist2_seg(a,b) }); }

// brd = do points on the border belong to convex?
// computes convex hull of given vector (inplace)
// returns size of convex hull
int graham (vec v[], int n, int brd) {
	for (int i = 1; i < n; i++) {
		if (v[i].x < v[0].x || (v[i].x == v[0].x && v[i].y < v[0].y))
			swap(v[0], v[i]);
	}

	sort(v+1, v+n, [v] (vec a, vec b) {
		int o = b.ccw(v[0], a);
		if (o) return (o == 1);
		return v[0].sq(a) < v[0].sq(b);
	});

	if (brd) {
		int s = n-1;
		while (s > 1 && v[s].ccw(v[s-1],v[0]) == 0)
			s--;
		for (int i = s; i < n - 1 - (i - s); i++)
			swap(v[i], v[n-1-(i-s)]);
	}

	int s = 0;
	for (int i = 0; i < n; i++) {
		if (s && v[s-1].x == v[i].x && v[s-1].y == v[i].y) continue;
		while (s >= 2 && v[s-1].ccw(v[s-2],v[i]) >= brd)
			s--;
		v[s++] = v[i];
	}

	return s;
}

const int N = 1e2+7;

int n;
double r;
vector<vec> v;
double x[2], y[2];

double solve (double x) {
	double lo = 200, hi = -100.;
	for (int i = 0; i < n; i++) {
		int j = (i+1)%n;
		lin ln(v[i],v[j]);
		vec it(x, (ln.c - ln.a*x)/ln.b);
		cout << it << " ";
		if (it.y == it.y && abs(it.y) < 200) {
			if (abs(ln.b) > eps) {
				lo = min(lo, it.y);
				hi = max(hi, it.y);
			}
		}

		if (abs(v[i].x - x) <= eps_d) {
			cout << v[i] << "! ";
			lo = min(lo, v[i].y);
			hi = max(hi, v[i].y);
		}
	}
	hi = min(hi, 200.); lo = max(lo, -100.);
	cout << x << " [" << lo << " " << hi << "]" << endl;

	int ts = 60;
	while (ts--) {
		double q1 = (lo+lo+hi)/3;
		double q2 = (lo+hi+hi)/3;

		double r1 = abs(cir({ vec(x,q1), r }).inter(v));
		double r2 = abs(cir({ vec(x,q2), r }).inter(v));

		if (r1 < r2)
			lo = q1;
		else
			hi = q2;
	}

	return abs(cir({ vec(x,lo), r }).inter(v));
}

int main () {

	while (scanf("%d %lf", &n, &r) != EOF) {
		cout << n << endl;
		v = vector<vec>(n);
		
		x[0] = 200;
		x[1] = -100;

		for (int i = 0; i < n; i++) {
			scanf("%lf %lf", &v[i].x, &v[i].y);
			cout << v[i] << " ";

			x[0] = min(x[0],v[i].x);
			x[1] = max(x[1],v[i].x);
		}
		cout << endl;

		double lo = x[0], hi = x[1];
		//int ts = 60;
		int ts = 50;
		while (ts--) {
			double q1 = (lo+lo+hi)/3;
			double q2 = (lo+hi+hi)/3;
			
			if (solve(q1) < solve(q2))
				lo = q1;
			else
				hi = q2;
		}

		double res = solve(lo);
		for (int i = 0; i < n; i++)
			res = max(res, abs(cir({ v[i], r }).inter(v)));

		printf("%.20f\n", res);
	}
}
accuracy: 0.7407407407407407
time_ms: 10
memory_kb: 3532
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define cout if (0) cout

// XXX without explanation marks untested functions

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

// NOT STANDART FROM HERE

// area de calota 2.pi.R.h (h altura)
// volume de calota pi.h/6 * (3r^2 + h^2)

 typedef double cood;
 cood eps = 1e-8;
// tests for double were made with eps = 1e-8

double eps_d = 1e-8; // necessary even in integer geometry, should be eps otherwise

const double pi = acos(-1.);

inline ll sq (ll x)
{ return x*x; }
inline double sq (double x)
{ return x*x; }

struct vec { // vector
	// === BASIC ===
	cood x, y;
	vec () : x(0), y(0) {}
	vec (cood a, cood b) : x(a), y(b) {}
	friend ostream& operator<<(ostream& os, vec o);

	vec operator - (vec o)
	{ return vec(x - o.x, y - o.y); }
	vec operator + (vec o)
	{ return vec(x + o.x, y + o.y); }
	vec operator * (cood o)
	{ return vec(x * o, y * o); }
	vec operator / (cood o)
	{ return vec(x / o, y / o); }
	cood operator ^ (vec o)
	{ return x * o.y - y * o.x; }
	cood operator * (vec o)
	{ return x * o.x + y * o.y; }

	// positive is (*this)b is clockwise from (*this)a
	double angle (vec a, vec b)
	{ return atan2((a-(*this))^(b-(*this)), (a-(*this))*(b-(*this))); }

	cood sq (vec o = vec())
	{ return ((*this)-o)*((*this)-o); }
	double nr (vec o = vec())
	{ return sqrt(sq(o)); }

	cood cross (vec a, vec b) // ccw signed area (positive if this is to the left of ab)
	{ return (b - a) ^ ((*this) - a); }
	int ccw (vec a, vec b) // which side is this from ab? (1 left, 0 over, -1 right)
	{ cood o = cross(a, b); return (eps < o) - (o < -eps); } 

	int dir (vec a, vec b) // direction of (this)a relative to (this)b (-1 opposite, 0 none, 1 same)
	{ cood o = ((*this) - a)*((*this) - b); return (eps < o) - (o < -eps); }

	cood inner (vec s, vec t) // (p-s)*(t-s) where p = this projected on st
	{ return ((*this) - s) * (t - s); }
	vec proj (vec s, vec t) // projection of this point over line st
	{ return s + (t - s)*(inner(s,t) / t.sq(s)); }

	vec rotate (double a) // rotate ccw by a (fails with ll)
	{ return vec(cos(a) * x - sin(a) * y, sin(a) * x + cos(a) * y); }
	vec rot90 () // rotate pi/2 ccw
	{ return vec(-y, x); }

	// === ADVANCED ===
	// ordering that defines the compare method
	// used only there, change it accordingly
	// sorts increasing on y and, then increasing on x
	bool operator < (const vec & o) const {
		if (y != o.y)
			return y < o.y;
		return x < o.x;
	}

	// full ordering (ccw angle from this+(1,0), distance to this)
	// is a < b?
	// PRECISION : ok with double if norm in [-1e9,5e3]
	bool compare (vec a, vec b) {
		if (((*this) < a) != ((*this) < b))
			return (*this) < a;
		int o = ccw(a,b);
		if (o) return o > 0;
		return a.dir((*this),b) < 0;
	}

	// is this inside segment st? (tip of segment included, change for dr < 0 otherwise)
	bool in_seg (vec s, vec t)
	{ return (ccw(s,t) == 0) && (dir(s,t) <= 0); }

	// squared distance from this to line defined by st
	double dist2_lin (vec s, vec t)
	{ return double(::sq(cross(s,t))) / t.sq(s); }
	// squared distance from this to segment st
	double dist2_seg (vec s, vec t) 
	{ return s.dir((*this),t) == t.dir((*this),s) ? dist2_lin(s,t) : min(sq(s),sq(t)); }

	// is this inside (borders included) the convex polygon v of size n?
	// if yes, prec is the vec that this on acw order from v[0] or 0 if there is no such
	// if not, prec is the predecessor of this when added to poly and succ is the sucessor
	// p should be a vector with [0..n-1]
	// n should be >= 2
	bool in_conv_poly (vec v[], int n, const vector<int> & p, int & prec, int & succ) {
		if (nr(v[0]) <= eps) {
			prec = 0;
			return 1;
		}

		if (n == 2) {
			if (in_seg(v[0],v[1]))
				return (prec = 1);

			if (ccw(v[0],v[1]) > 0) {
				prec = 1;
				succ = 0;
			} else if (ccw(v[0],v[1]) < 0) {
				prec = 0;
				succ = 1;
			} else {
				prec = succ = (v[0].dir((*this),v[1]) < 0);
			}
			return 0;
		}
		
		if (ccw(v[0],v[1]) > 0 || ccw(v[0],v[n-1]) < 0) {
		// case where v[0] is not removed
			// last diagonal before or over this
			int di = lower_bound(p.begin() + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) >= 0;
			}) - p.begin() - 1;

			// is this inside the polygon?
			prec = di;
			if (di == n-1) {
			// last segment
				if (ccw(v[0],v[n-1]) == 0 && ccw(v[n-2],v[n-1]) >= 0)
					return 1;
			} else {
			// inside otherwise
				if (ccw(v[di],v[di+1]) >= 0)
					return 1;
			}

			// last that stays before (or eq to) di
			prec = lower_bound(p.begin() + 1, p.begin() + di + 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;

			// first that stays after di
			succ = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v,n] (int i, int j) {
				assert(j == -1);
				return ccw(v[(i+1)%n],v[i]) >= 0;
			}) - p.begin();
			if (succ == n) succ = 0;
		} else {
		// case where v[0] is removed
			// first diagonal before of over this
			// di is certainly not removed
			int di = lower_bound(p.begin() + 1, p.end() - 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) < 0;
			}) - p.begin();

			// first that stays (<= di)
			succ = lower_bound(p.begin(), p.begin() + di, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i+1],v[i]) >= 0;
			}) - p.begin();

			// last that stays (>= di)
			prec = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;
		}
		return 0;
	}
};
ostream& operator<<(ostream& os, vec o)
{ return os << '(' << o.x << ", " << o.y << ')'; }

struct lin { // line
	cood a, b, c; // a*x + b*y = c

	lin () {}
	lin (cood x, cood y, cood z) : a(x), b(y), c(z) {}
	lin (vec s, vec t) : a(t.y - s.y), b(s.x - t.x), c(a * s.x + b * s.y) {}

	lin parll (vec p) // parallel to this through p
	{ return lin(a, b, a * p.x + b * p.y); }
	lin perp ()
	{ return lin(-b, a, c); }

	vec inter (lin o) {
		cood d = a * o.b - o.a * b;
		if (d < eps && -eps < d) throw 0; // parallel
		return vec((o.b * c - b * o.c) / d, (a * o.c - o.a * c) / d);
	}
};

struct cir { // circle
	vec c; cood r;

	// borders included
	bool contains (vec w)
	{ return c.sq(w) <= sq(r) + eps; }
	bool has_inter (cir o)
	{ return c.sq(o.c) <= sq(r + o.r) + eps; }
	bool has_inter_lin (vec s, vec t)
	{ return c.dist2_lin(s,t) <= sq(r) + eps_d; }
	bool has_inter_seg (vec s, vec t)
	{ return c.dist2_seg(s,t) <= sq(r); }

	// borders not included
	bool contains (cir o)
	{ return (o.r < r - eps && c.sq(o.c) < sq(r - o.r) - eps); }

	// ccw oriented area of arc from a to b
	double arc_area (vec a, vec b) {
		double ang = c.angle(a,b);
		return r*r*ang*.5;
	}

	// double only
	pair<vec,vec> inter_pts (cir o) {
		assert(has_inter(o) && !contains(o)); // fully contained case
		double d = c.nr(o.c);
		double a = (r*r + d*d - o.r*o.r) / (2.*d); // r*cos(ans,v,c.v)
		double h = sqrt(r*r - a*a);
		if (h != h) h = 0;
		vec p = o.c - c;
		return pair<vec,vec>(c + p*(a/d) + (p.rot90()*(h/d)), c + p*(a/d) - (p.rot90()*(h/d)));
	}

	// double only XXX careful precision
	pair<vec,vec> inter_pts (vec s, vec t) { 
		assert(has_inter_lin(s,t));
		double h2 = c.dist2_lin(s,t);
		double d = sqrt(c.sq(t) - h2);
		if (d != d) d = 0;
		vec p = (s-t);
		vec m = t + p*(d/p.nr());
		vec m_b = t - p*(d/p.nr());
		if (m_b.sq(c) < m.sq(c))
			m = m_b;

		d = sqrt(r*r - h2);
		if (d != d) d = 0;
		pair<vec,vec> res(m + p*(d/p.nr()), m - p*(d/p.nr()));
		if (res.first.sq(t) > res.second.sq(t))
			swap(res.first, res.second);
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with triangle (this.c,a,b)
	double inter (vec a, vec b) {
		double res = 0.;
		bool inv = 0;
		if (contains(b)) {
			swap(a,b);
			inv = 1;
		}

		if (contains(b)) {
			res = c.cross(a,b)*.5;
		} else if (contains(a)) {
			pair<vec,vec> rt = inter_pts(a,b);
			vec q = rt.first;
			//if (!q.in_seg(a,b))
			if (rt.second.dist2_seg(a,b) < q.dist2_seg(a,b))
				q = rt.second;

			res += c.cross(a,q)*.5;
			res += arc_area(q,b);
		} else if (has_inter_seg(a, b)) {
			pair<vec,vec> rt = inter_pts(b,a);

			res += arc_area(a,rt.first);
			res += c.cross(rt.first,rt.second)*.5;
			res += arc_area(rt.second,b);
		} else {
			res += arc_area(a,b);
		}

		if (inv) res = -res;
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with polygon
	double inter (vector<vec> & p) {
		double res = 0;
		for (int i = 0; i < p.size(); i++)
			res += inter(p[i],p[(i+1)%p.size()]);
		return res;
	}
};

// do the segments ab and cd intersect? (borders included) XXX
bool inter_seg (vec a, vec b, vec c, vec d) {
	if (a.in_seg(c, d) || b.in_seg(c, d) || c.in_seg(a, b) || d.in_seg(a, b))
		return true;
	return (c.ccw(a, b) * d.ccw(a, b) == -1 && a.ccw(c, d) * b.ccw(c, d) == -1);
}

// squared distance from segments ab and cd XXX
double dist2_seg (vec a, vec b, vec c, vec d)
{ return inter_seg(a,b,c,d) ? 0. : min({ a.dist2_seg(c,d), b.dist2_seg(c,d), c.dist2_seg(a,b), d.dist2_seg(a,b) }); }

// brd = do points on the border belong to convex?
// computes convex hull of given vector (inplace)
// returns size of convex hull
int graham (vec v[], int n, int brd) {
	for (int i = 1; i < n; i++) {
		if (v[i].x < v[0].x || (v[i].x == v[0].x && v[i].y < v[0].y))
			swap(v[0], v[i]);
	}

	sort(v+1, v+n, [v] (vec a, vec b) {
		int o = b.ccw(v[0], a);
		if (o) return (o == 1);
		return v[0].sq(a) < v[0].sq(b);
	});

	if (brd) {
		int s = n-1;
		while (s > 1 && v[s].ccw(v[s-1],v[0]) == 0)
			s--;
		for (int i = s; i < n - 1 - (i - s); i++)
			swap(v[i], v[n-1-(i-s)]);
	}

	int s = 0;
	for (int i = 0; i < n; i++) {
		if (s && v[s-1].x == v[i].x && v[s-1].y == v[i].y) continue;
		while (s >= 2 && v[s-1].ccw(v[s-2],v[i]) >= brd)
			s--;
		v[s++] = v[i];
	}

	return s;
}

const int N = 1e2+7;

int n;
double r;
vector<vec> v;
double x[2], y[2];

double solve (double x) {
	double lo = 200, hi = -100.;
	for (int i = 0; i < n; i++) {
		int j = (i+1)%n;
		lin ln(v[i],v[j]);
		vec it(x, (ln.c - ln.a*x)/ln.b);
		cout << it << " ";
		if (it.y == it.y && abs(it.y) < 200) {
			if (abs(ln.b) > eps) {
				lo = min(lo, it.y);
				hi = max(hi, it.y);
			}
		}

		if (abs(v[i].x - x) <= eps_d) {
			cout << v[i] << "! ";
			lo = min(lo, v[i].y);
			hi = max(hi, v[i].y);
		}
	}
	hi = min(hi, 200.); lo = max(lo, -100.);
	cout << x << " [" << lo << " " << hi << "]" << endl;

	int ts = 60;
	while (ts--) {
		double q1 = (lo+lo+hi)/3;
		double q2 = (lo+hi+hi)/3;

		double r1 = abs(cir({ vec(x,q1), r }).inter(v));
		double r2 = abs(cir({ vec(x,q2), r }).inter(v));

		if (r1 < r2)
			lo = q1;
		else
			hi = q2;
	}

	return abs(cir({ vec(x,lo), r }).inter(v));
}

int main () {

	while (scanf("%d %lf", &n, &r) != EOF) {
		cout << n << endl;
		v = vector<vec>(n);
		
		x[0] = 200;
		x[1] = -100;

		for (int i = 0; i < n; i++) {
			scanf("%lf %lf", &v[i].x, &v[i].y);
			cout << v[i] << " ";

			x[0] = min(x[0],v[i].x);
			x[1] = max(x[1],v[i].x);
		}
		cout << endl;

		double lo = x[0], hi = x[1];
		int ts = 60;
		while (ts--) {
			double q1 = (lo+lo+hi)/3;
			double q2 = (lo+hi+hi)/3;
			
			if (solve(q1) < solve(q2))
				lo = q1;
			else
				hi = q2;
		}

		printf("%.20f\n", solve(lo));
	}
}
accuracy: 0.7407407407407407
time_ms: 10
memory_kb: 3528
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define cout if (0) cout

// XXX without explanation marks untested functions

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

// NOT STANDART FROM HERE

// area de calota 2.pi.R.h (h altura)
// volume de calota pi.h/6 * (3r^2 + h^2)

 typedef double cood;
 cood eps = 1e-8;
// tests for double were made with eps = 1e-8

double eps_d = 1e-8; // necessary even in integer geometry, should be eps otherwise

const double pi = acos(-1.);

inline ll sq (ll x)
{ return x*x; }
inline double sq (double x)
{ return x*x; }

struct vec { // vector
	// === BASIC ===
	cood x, y;
	vec () : x(0), y(0) {}
	vec (cood a, cood b) : x(a), y(b) {}
	friend ostream& operator<<(ostream& os, vec o);

	vec operator - (vec o)
	{ return vec(x - o.x, y - o.y); }
	vec operator + (vec o)
	{ return vec(x + o.x, y + o.y); }
	vec operator * (cood o)
	{ return vec(x * o, y * o); }
	vec operator / (cood o)
	{ return vec(x / o, y / o); }
	cood operator ^ (vec o)
	{ return x * o.y - y * o.x; }
	cood operator * (vec o)
	{ return x * o.x + y * o.y; }

	// positive is (*this)b is clockwise from (*this)a
	double angle (vec a, vec b)
	{ return atan2((a-(*this))^(b-(*this)), (a-(*this))*(b-(*this))); }

	cood sq (vec o = vec())
	{ return ((*this)-o)*((*this)-o); }
	double nr (vec o = vec())
	{ return sqrt(sq(o)); }

	cood cross (vec a, vec b) // ccw signed area (positive if this is to the left of ab)
	{ return (b - a) ^ ((*this) - a); }
	int ccw (vec a, vec b) // which side is this from ab? (1 left, 0 over, -1 right)
	{ cood o = cross(a, b); return (eps < o) - (o < -eps); } 

	int dir (vec a, vec b) // direction of (this)a relative to (this)b (-1 opposite, 0 none, 1 same)
	{ cood o = ((*this) - a)*((*this) - b); return (eps < o) - (o < -eps); }

	cood inner (vec s, vec t) // (p-s)*(t-s) where p = this projected on st
	{ return ((*this) - s) * (t - s); }
	vec proj (vec s, vec t) // projection of this point over line st
	{ return s + (t - s)*(inner(s,t) / t.sq(s)); }

	vec rotate (double a) // rotate ccw by a (fails with ll)
	{ return vec(cos(a) * x - sin(a) * y, sin(a) * x + cos(a) * y); }
	vec rot90 () // rotate pi/2 ccw
	{ return vec(-y, x); }

	// === ADVANCED ===
	// ordering that defines the compare method
	// used only there, change it accordingly
	// sorts increasing on y and, then increasing on x
	bool operator < (const vec & o) const {
		if (y != o.y)
			return y < o.y;
		return x < o.x;
	}

	// full ordering (ccw angle from this+(1,0), distance to this)
	// is a < b?
	// PRECISION : ok with double if norm in [-1e9,5e3]
	bool compare (vec a, vec b) {
		if (((*this) < a) != ((*this) < b))
			return (*this) < a;
		int o = ccw(a,b);
		if (o) return o > 0;
		return a.dir((*this),b) < 0;
	}

	// is this inside segment st? (tip of segment included, change for dr < 0 otherwise)
	bool in_seg (vec s, vec t)
	{ return (ccw(s,t) == 0) && (dir(s,t) <= 0); }

	// squared distance from this to line defined by st
	double dist2_lin (vec s, vec t)
	{ return double(::sq(cross(s,t))) / t.sq(s); }
	// squared distance from this to segment st
	double dist2_seg (vec s, vec t) 
	{ return s.dir((*this),t) == t.dir((*this),s) ? dist2_lin(s,t) : min(sq(s),sq(t)); }

	// is this inside (borders included) the convex polygon v of size n?
	// if yes, prec is the vec that this on acw order from v[0] or 0 if there is no such
	// if not, prec is the predecessor of this when added to poly and succ is the sucessor
	// p should be a vector with [0..n-1]
	// n should be >= 2
	bool in_conv_poly (vec v[], int n, const vector<int> & p, int & prec, int & succ) {
		if (nr(v[0]) <= eps) {
			prec = 0;
			return 1;
		}

		if (n == 2) {
			if (in_seg(v[0],v[1]))
				return (prec = 1);

			if (ccw(v[0],v[1]) > 0) {
				prec = 1;
				succ = 0;
			} else if (ccw(v[0],v[1]) < 0) {
				prec = 0;
				succ = 1;
			} else {
				prec = succ = (v[0].dir((*this),v[1]) < 0);
			}
			return 0;
		}
		
		if (ccw(v[0],v[1]) > 0 || ccw(v[0],v[n-1]) < 0) {
		// case where v[0] is not removed
			// last diagonal before or over this
			int di = lower_bound(p.begin() + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) >= 0;
			}) - p.begin() - 1;

			// is this inside the polygon?
			prec = di;
			if (di == n-1) {
			// last segment
				if (ccw(v[0],v[n-1]) == 0 && ccw(v[n-2],v[n-1]) >= 0)
					return 1;
			} else {
			// inside otherwise
				if (ccw(v[di],v[di+1]) >= 0)
					return 1;
			}

			// last that stays before (or eq to) di
			prec = lower_bound(p.begin() + 1, p.begin() + di + 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;

			// first that stays after di
			succ = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v,n] (int i, int j) {
				assert(j == -1);
				return ccw(v[(i+1)%n],v[i]) >= 0;
			}) - p.begin();
			if (succ == n) succ = 0;
		} else {
		// case where v[0] is removed
			// first diagonal before of over this
			// di is certainly not removed
			int di = lower_bound(p.begin() + 1, p.end() - 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) < 0;
			}) - p.begin();

			// first that stays (<= di)
			succ = lower_bound(p.begin(), p.begin() + di, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i+1],v[i]) >= 0;
			}) - p.begin();

			// last that stays (>= di)
			prec = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;
		}
		return 0;
	}
};
ostream& operator<<(ostream& os, vec o)
{ return os << '(' << o.x << ", " << o.y << ')'; }

struct lin { // line
	cood a, b, c; // a*x + b*y = c

	lin () {}
	lin (cood x, cood y, cood z) : a(x), b(y), c(z) {}
	lin (vec s, vec t) : a(t.y - s.y), b(s.x - t.x), c(a * s.x + b * s.y) {}

	lin parll (vec p) // parallel to this through p
	{ return lin(a, b, a * p.x + b * p.y); }
	lin perp ()
	{ return lin(-b, a, c); }

	vec inter (lin o) {
		cood d = a * o.b - o.a * b;
		if (d < eps && -eps < d) throw 0; // parallel
		return vec((o.b * c - b * o.c) / d, (a * o.c - o.a * c) / d);
	}
};

struct cir { // circle
	vec c; cood r;

	// borders included
	bool contains (vec w)
	{ return c.sq(w) <= sq(r) + eps; }
	bool has_inter (cir o)
	{ return c.sq(o.c) <= sq(r + o.r) + eps; }
	bool has_inter_lin (vec s, vec t)
	{ return c.dist2_lin(s,t) <= sq(r) + eps_d; }
	bool has_inter_seg (vec s, vec t)
	{ return c.dist2_seg(s,t) <= sq(r); }

	// borders not included
	bool contains (cir o)
	{ return (o.r < r - eps && c.sq(o.c) < sq(r - o.r) - eps); }

	// ccw oriented area of arc from a to b
	double arc_area (vec a, vec b) {
		double ang = c.angle(a,b);
		return r*r*ang*.5;
	}

	// double only
	pair<vec,vec> inter_pts (cir o) {
		assert(has_inter(o) && !contains(o)); // fully contained case
		double d = c.nr(o.c);
		double a = (r*r + d*d - o.r*o.r) / (2.*d); // r*cos(ans,v,c.v)
		double h = sqrt(r*r - a*a);
		if (h != h) h = 0;
		vec p = o.c - c;
		return pair<vec,vec>(c + p*(a/d) + (p.rot90()*(h/d)), c + p*(a/d) - (p.rot90()*(h/d)));
	}

	// double only XXX careful precision
	pair<vec,vec> inter_pts (vec s, vec t) { 
		assert(has_inter_lin(s,t));
		double h2 = c.dist2_lin(s,t);
		double d = sqrt(c.sq(t) - h2);
		if (d != d) d = 0;
		vec p = (s-t);
		vec m = t + p*(d/p.nr());
		vec m_b = t - p*(d/p.nr());
		if (m_b.sq(c) < m.sq(c))
			m = m_b;

		d = sqrt(r*r - h2);
		if (d != d) d = 0;
		pair<vec,vec> res(m + p*(d/p.nr()), m - p*(d/p.nr()));
		if (res.first.sq(t) > res.second.sq(t))
			swap(res.first, res.second);
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with triangle (this.c,a,b)
	double inter (vec a, vec b) {
		double res = 0.;
		bool inv = 0;
		if (contains(b)) {
			swap(a,b);
			inv = 1;
		}

		if (contains(b)) {
			res = c.cross(a,b)*.5;
		} else if (contains(a)) {
			pair<vec,vec> rt = inter_pts(a,b);
			vec q = rt.first;
			if (!q.in_seg(a,b))
			//if (rt.second.dist2_seg(a,b) < q.dist2_seg(a,b))
				q = rt.second;

			res += c.cross(a,q)*.5;
			res += arc_area(q,b);
		} else if (has_inter_seg(a, b)) {
			pair<vec,vec> rt = inter_pts(b,a);

			res += arc_area(a,rt.first);
			res += c.cross(rt.first,rt.second)*.5;
			res += arc_area(rt.second,b);
		} else {
			res += arc_area(a,b);
		}

		if (inv) res = -res;
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with polygon
	double inter (vector<vec> & p) {
		double res = 0;
		for (int i = 0; i < p.size(); i++)
			res += inter(p[i],p[(i+1)%p.size()]);
		return res;
	}
};

// do the segments ab and cd intersect? (borders included) XXX
bool inter_seg (vec a, vec b, vec c, vec d) {
	if (a.in_seg(c, d) || b.in_seg(c, d) || c.in_seg(a, b) || d.in_seg(a, b))
		return true;
	return (c.ccw(a, b) * d.ccw(a, b) == -1 && a.ccw(c, d) * b.ccw(c, d) == -1);
}

// squared distance from segments ab and cd XXX
double dist2_seg (vec a, vec b, vec c, vec d)
{ return inter_seg(a,b,c,d) ? 0. : min({ a.dist2_seg(c,d), b.dist2_seg(c,d), c.dist2_seg(a,b), d.dist2_seg(a,b) }); }

// brd = do points on the border belong to convex?
// computes convex hull of given vector (inplace)
// returns size of convex hull
int graham (vec v[], int n, int brd) {
	for (int i = 1; i < n; i++) {
		if (v[i].x < v[0].x || (v[i].x == v[0].x && v[i].y < v[0].y))
			swap(v[0], v[i]);
	}

	sort(v+1, v+n, [v] (vec a, vec b) {
		int o = b.ccw(v[0], a);
		if (o) return (o == 1);
		return v[0].sq(a) < v[0].sq(b);
	});

	if (brd) {
		int s = n-1;
		while (s > 1 && v[s].ccw(v[s-1],v[0]) == 0)
			s--;
		for (int i = s; i < n - 1 - (i - s); i++)
			swap(v[i], v[n-1-(i-s)]);
	}

	int s = 0;
	for (int i = 0; i < n; i++) {
		if (s && v[s-1].x == v[i].x && v[s-1].y == v[i].y) continue;
		while (s >= 2 && v[s-1].ccw(v[s-2],v[i]) >= brd)
			s--;
		v[s++] = v[i];
	}

	return s;
}

const int N = 1e2+7;

int n;
double r;
vector<vec> v;
double x[2], y[2];

double solve (double x) {
	double lo = 200, hi = -100.;
	for (int i = 0; i < n; i++) {
		int j = (i+1)%n;
		lin ln(v[i],v[j]);
		vec it(x, (ln.c - ln.a*x)/ln.b);
		cout << it << " ";
		if (it.y == it.y && abs(it.y) < 200) {
			if (abs(ln.b) > eps) {
				lo = min(lo, it.y);
				hi = max(hi, it.y);
			}
		}

		if (abs(v[i].x - x) <= eps_d) {
			cout << v[i] << "! ";
			lo = min(lo, v[i].y);
			hi = max(hi, v[i].y);
		}
	}
	hi = min(hi, 200.); lo = max(lo, -100.);
	cout << x << " [" << lo << " " << hi << "]" << endl;

	int ts = 60;
	while (ts--) {
		double q1 = (lo+lo+hi)/3;
		double q2 = (lo+hi+hi)/3;

		double r1 = abs(cir({ vec(x,q1), r }).inter(v));
		double r2 = abs(cir({ vec(x,q2), r }).inter(v));

		if (r1 < r2)
			lo = q1;
		else
			hi = q2;
	}

	return abs(cir({ vec(x,lo), r }).inter(v));
}

int main () {

	while (scanf("%d %lf", &n, &r) != EOF) {
		cout << n << endl;
		v = vector<vec>(n);
		
		x[0] = 200;
		x[1] = -100;

		for (int i = 0; i < n; i++) {
			scanf("%lf %lf", &v[i].x, &v[i].y);
			cout << v[i] << " ";

			x[0] = min(x[0],v[i].x);
			x[1] = max(x[1],v[i].x);
		}
		cout << endl;

		double lo = x[0], hi = x[1];
		int ts = 60;
		while (ts--) {
			double q1 = (lo+lo+hi)/3;
			double q2 = (lo+hi+hi)/3;
			
			if (solve(q1) < solve(q2))
				lo = q1;
			else
				hi = q2;
		}

		printf("%.20f\n", solve(lo));
	}
}
accuracy: 0.7407407407407407
time_ms: 20
memory_kb: 3528
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define cout if (0) cout

// XXX without explanation marks untested functions

using namespace std;
typedef long long int ll;
typedef pair<ll,ll> pii;
#define pb push_back

// NOT STANDART FROM HERE

// area de calota 2.pi.R.h (h altura)
// volume de calota pi.h/6 * (3r^2 + h^2)

 typedef double cood;
 cood eps = 1e-8;
// tests for double were made with eps = 1e-8

double eps_d = 1e-8; // necessary even in integer geometry, should be eps otherwise

const double pi = acos(-1.);

inline ll sq (ll x)
{ return x*x; }
inline double sq (double x)
{ return x*x; }

struct vec { // vector
	// === BASIC ===
	cood x, y;
	vec () : x(0), y(0) {}
	vec (cood a, cood b) : x(a), y(b) {}
	friend ostream& operator<<(ostream& os, vec o);

	vec operator - (vec o)
	{ return vec(x - o.x, y - o.y); }
	vec operator + (vec o)
	{ return vec(x + o.x, y + o.y); }
	vec operator * (cood o)
	{ return vec(x * o, y * o); }
	vec operator / (cood o)
	{ return vec(x / o, y / o); }
	cood operator ^ (vec o)
	{ return x * o.y - y * o.x; }
	cood operator * (vec o)
	{ return x * o.x + y * o.y; }

	// positive is (*this)b is clockwise from (*this)a
	double angle (vec a, vec b)
	{ return atan2((a-(*this))^(b-(*this)), (a-(*this))*(b-(*this))); }

	cood sq (vec o = vec())
	{ return ((*this)-o)*((*this)-o); }
	double nr (vec o = vec())
	{ return sqrt(sq(o)); }

	cood cross (vec a, vec b) // ccw signed area (positive if this is to the left of ab)
	{ return (b - a) ^ ((*this) - a); }
	int ccw (vec a, vec b) // which side is this from ab? (1 left, 0 over, -1 right)
	{ cood o = cross(a, b); return (eps < o) - (o < -eps); } 

	int dir (vec a, vec b) // direction of (this)a relative to (this)b (-1 opposite, 0 none, 1 same)
	{ cood o = ((*this) - a)*((*this) - b); return (eps < o) - (o < -eps); }

	cood inner (vec s, vec t) // (p-s)*(t-s) where p = this projected on st
	{ return ((*this) - s) * (t - s); }
	vec proj (vec s, vec t) // projection of this point over line st
	{ return s + (t - s)*(inner(s,t) / t.sq(s)); }

	vec rotate (double a) // rotate ccw by a (fails with ll)
	{ return vec(cos(a) * x - sin(a) * y, sin(a) * x + cos(a) * y); }
	vec rot90 () // rotate pi/2 ccw
	{ return vec(-y, x); }

	// === ADVANCED ===
	// ordering that defines the compare method
	// used only there, change it accordingly
	// sorts increasing on y and, then increasing on x
	bool operator < (const vec & o) const {
		if (y != o.y)
			return y < o.y;
		return x < o.x;
	}

	// full ordering (ccw angle from this+(1,0), distance to this)
	// is a < b?
	// PRECISION : ok with double if norm in [-1e9,5e3]
	bool compare (vec a, vec b) {
		if (((*this) < a) != ((*this) < b))
			return (*this) < a;
		int o = ccw(a,b);
		if (o) return o > 0;
		return a.dir((*this),b) < 0;
	}

	// is this inside segment st? (tip of segment included, change for dr < 0 otherwise)
	bool in_seg (vec s, vec t)
	{ return (ccw(s,t) == 0) && (dir(s,t) <= 0); }

	// squared distance from this to line defined by st
	double dist2_lin (vec s, vec t)
	{ return double(::sq(cross(s,t))) / t.sq(s); }
	// squared distance from this to segment st
	double dist2_seg (vec s, vec t) 
	{ return s.dir((*this),t) == t.dir((*this),s) ? dist2_lin(s,t) : min(sq(s),sq(t)); }

	// is this inside (borders included) the convex polygon v of size n?
	// if yes, prec is the vec that this on acw order from v[0] or 0 if there is no such
	// if not, prec is the predecessor of this when added to poly and succ is the sucessor
	// p should be a vector with [0..n-1]
	// n should be >= 2
	bool in_conv_poly (vec v[], int n, const vector<int> & p, int & prec, int & succ) {
		if (nr(v[0]) <= eps) {
			prec = 0;
			return 1;
		}

		if (n == 2) {
			if (in_seg(v[0],v[1]))
				return (prec = 1);

			if (ccw(v[0],v[1]) > 0) {
				prec = 1;
				succ = 0;
			} else if (ccw(v[0],v[1]) < 0) {
				prec = 0;
				succ = 1;
			} else {
				prec = succ = (v[0].dir((*this),v[1]) < 0);
			}
			return 0;
		}
		
		if (ccw(v[0],v[1]) > 0 || ccw(v[0],v[n-1]) < 0) {
		// case where v[0] is not removed
			// last diagonal before or over this
			int di = lower_bound(p.begin() + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) >= 0;
			}) - p.begin() - 1;

			// is this inside the polygon?
			prec = di;
			if (di == n-1) {
			// last segment
				if (ccw(v[0],v[n-1]) == 0 && ccw(v[n-2],v[n-1]) >= 0)
					return 1;
			} else {
			// inside otherwise
				if (ccw(v[di],v[di+1]) >= 0)
					return 1;
			}

			// last that stays before (or eq to) di
			prec = lower_bound(p.begin() + 1, p.begin() + di + 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;

			// first that stays after di
			succ = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v,n] (int i, int j) {
				assert(j == -1);
				return ccw(v[(i+1)%n],v[i]) >= 0;
			}) - p.begin();
			if (succ == n) succ = 0;
		} else {
		// case where v[0] is removed
			// first diagonal before of over this
			// di is certainly not removed
			int di = lower_bound(p.begin() + 1, p.end() - 1, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[0],v[i]) < 0;
			}) - p.begin();

			// first that stays (<= di)
			succ = lower_bound(p.begin(), p.begin() + di, -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i+1],v[i]) >= 0;
			}) - p.begin();

			// last that stays (>= di)
			prec = lower_bound(p.begin() + di + 1, p.end(), -1, [this,v] (int i, int j) {
				assert(j == -1);
				return ccw(v[i-1],v[i]) > 0;
			}) - p.begin() - 1;
		}
		return 0;
	}
};
ostream& operator<<(ostream& os, vec o)
{ return os << '(' << o.x << ", " << o.y << ')'; }

struct lin { // line
	cood a, b, c; // a*x + b*y = c

	lin () {}
	lin (cood x, cood y, cood z) : a(x), b(y), c(z) {}
	lin (vec s, vec t) : a(t.y - s.y), b(s.x - t.x), c(a * s.x + b * s.y) {}

	lin parll (vec p) // parallel to this through p
	{ return lin(a, b, a * p.x + b * p.y); }
	lin perp ()
	{ return lin(-b, a, c); }

	vec inter (lin o) {
		cood d = a * o.b - o.a * b;
		if (d < eps && -eps < d) throw 0; // parallel
		return vec((o.b * c - b * o.c) / d, (a * o.c - o.a * c) / d);
	}
};

struct cir { // circle
	vec c; cood r;

	// borders included
	bool contains (vec w)
	{ return c.sq(w) <= sq(r) + eps; }
	bool has_inter (cir o)
	{ return c.sq(o.c) <= sq(r + o.r) + eps; }
	bool has_inter_lin (vec s, vec t)
	{ return c.dist2_lin(s,t) <= sq(r) + eps_d; }
	bool has_inter_seg (vec s, vec t)
	{ return c.dist2_seg(s,t) <= sq(r); }

	// borders not included
	bool contains (cir o)
	{ return (o.r < r - eps && c.sq(o.c) < sq(r - o.r) - eps); }

	// ccw oriented area of arc from a to b
	double arc_area (vec a, vec b) {
		double ang = c.angle(a,b);
		return r*r*ang*.5;
	}

	// double only
	pair<vec,vec> inter_pts (cir o) {
		assert(has_inter(o) && !contains(o)); // fully contained case
		double d = c.nr(o.c);
		double a = (r*r + d*d - o.r*o.r) / (2.*d); // r*cos(ans,v,c.v)
		double h = sqrt(r*r - a*a);
		if (h != h) h = 0;
		vec p = o.c - c;
		return pair<vec,vec>(c + p*(a/d) + (p.rot90()*(h/d)), c + p*(a/d) - (p.rot90()*(h/d)));
	}

	// double only XXX careful precision
	pair<vec,vec> inter_pts (vec s, vec t) { 
		assert(has_inter_lin(s,t));
		double h2 = c.dist2_lin(s,t);
		double d = sqrt(c.sq(t) - h2);
		if (d != d) d = 0;
		vec p = (s-t);
		vec m = t + p*(d/p.nr());
		vec m_b = t - p*(d/p.nr());
		if (m_b.sq(c) < m.sq(c))
			m = m_b;

		d = sqrt(r*r - h2);
		if (d != d) d = 0;
		pair<vec,vec> res(m + p*(d/p.nr()), m - p*(d/p.nr()));
		if (res.first.sq(t) > res.second.sq(t))
			swap(res.first, res.second);
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with triangle (this.c,a,b)
	double inter (vec a, vec b) {
		double res = 0.;
		bool inv = 0;
		if (contains(b)) {
			swap(a,b);
			inv = 1;
		}

		if (contains(b)) {
			res = c.cross(a,b)*.5;
		} else if (contains(a)) {
			pair<vec,vec> rt = inter_pts(a,b);
			vec q = rt.first;
			if (rt.second.dist2_seg(a,b) < q.dist2_seg(a,b))
				q = rt.second;

			res += c.cross(a,q)*.5;
			res += arc_area(q,b);
		} else if (has_inter_seg(a, b)) {
			pair<vec,vec> rt = inter_pts(b,a);

			res += arc_area(a,rt.first);
			res += c.cross(rt.first,rt.second)*.5;
			res += arc_area(rt.second,b);
		} else {
			res += arc_area(a,b);
		}

		if (inv) res = -res;
		return res;
	}

	// double only XXX not tested
	// signed area of intersection of this with polygon
	double inter (vector<vec> & p) {
		double res = 0;
		for (int i = 0; i < p.size(); i++)
			res += inter(p[i],p[(i+1)%p.size()]);
		return res;
	}
};

// do the segments ab and cd intersect? (borders included) XXX
bool inter_seg (vec a, vec b, vec c, vec d) {
	if (a.in_seg(c, d) || b.in_seg(c, d) || c.in_seg(a, b) || d.in_seg(a, b))
		return true;
	return (c.ccw(a, b) * d.ccw(a, b) == -1 && a.ccw(c, d) * b.ccw(c, d) == -1);
}

// squared distance from segments ab and cd XXX
double dist2_seg (vec a, vec b, vec c, vec d)
{ return inter_seg(a,b,c,d) ? 0. : min({ a.dist2_seg(c,d), b.dist2_seg(c,d), c.dist2_seg(a,b), d.dist2_seg(a,b) }); }

// brd = do points on the border belong to convex?
// computes convex hull of given vector (inplace)
// returns size of convex hull
int graham (vec v[], int n, int brd) {
	for (int i = 1; i < n; i++) {
		if (v[i].x < v[0].x || (v[i].x == v[0].x && v[i].y < v[0].y))
			swap(v[0], v[i]);
	}

	sort(v+1, v+n, [v] (vec a, vec b) {
		int o = b.ccw(v[0], a);
		if (o) return (o == 1);
		return v[0].sq(a) < v[0].sq(b);
	});

	if (brd) {
		int s = n-1;
		while (s > 1 && v[s].ccw(v[s-1],v[0]) == 0)
			s--;
		for (int i = s; i < n - 1 - (i - s); i++)
			swap(v[i], v[n-1-(i-s)]);
	}

	int s = 0;
	for (int i = 0; i < n; i++) {
		if (s && v[s-1].x == v[i].x && v[s-1].y == v[i].y) continue;
		while (s >= 2 && v[s-1].ccw(v[s-2],v[i]) >= brd)
			s--;
		v[s++] = v[i];
	}

	return s;
}

const int N = 1e2+7;

int n;
double r;
vector<vec> v;
double x[2], y[2];

double solve (double x) {
	double lo = 200, hi = -100.;
	for (int i = 0; i < n; i++) {
		int j = (i+1)%n;
		if (abs(v[i].x - v[j].x) > eps_d) {
			lin ln(v[i],v[j]);
			vec it(x, (ln.c - ln.a*x)/ln.b);
			cout << it << " ";
			if (abs(ln.b) > eps) {
				lo = min(lo, it.y);
				hi = max(hi, it.y);
			}
		}

		if (abs(v[i].x - x) <= eps_d) {
			cout << v[i] << "! ";
			lo = min(lo, v[i].y);
			hi = max(hi, v[i].y);
		}
	}
	hi = min(hi, 200.); lo = max(lo, -100.);
	cout << x << " [" << lo << " " << hi << "]" << endl;

	int ts = 60;
	while (ts--) {
		double q1 = (lo+lo+hi)/3;
		double q2 = (lo+hi+hi)/3;

		double r1 = abs(cir({ vec(x,q1), r }).inter(v));
		double r2 = abs(cir({ vec(x,q2), r }).inter(v));

		if (r1 < r2)
			lo = q1;
		else
			hi = q2;
	}

	return abs(cir({ vec(x,lo), r }).inter(v));
}

int main () {

	while (scanf("%d %lf", &n, &r) != EOF) {
		cout << n << endl;
		v = vector<vec>(n);
		
		x[0] = 200;
		x[1] = -100;

		for (int i = 0; i < n; i++) {
			scanf("%lf %lf", &v[i].x, &v[i].y);
			cout << v[i] << " ";

			x[0] = min(x[0],v[i].x);
			x[1] = max(x[1],v[i].x);
		}
		cout << endl;

		double lo = x[0], hi = x[1];
		int ts = 60;
		while (ts--) {
			double q1 = (lo+lo+hi)/3;
			double q2 = (lo+hi+hi)/3;
			
			if (solve(q1) < solve(q2))
				lo = q1;
			else
				hi = q2;
		}

		printf("%.20f\n", solve(lo));
	}
}
accuracy: 0.25925925925925924
time_ms: 10
memory_kb: 3472
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define mem(a,b) memset((a),(b),sizeof(a))
#define MP make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) x.size()
#define all(x) x.begin(),x.end()
using namespace std;
#define _GLIBCXX_PERMIT_BACKWARD_HASH
#include <ext/hash_map>
using namespace __gnu_cxx;
struct str_hash{size_t operator()(const string& str)const{return __stl_hash_string(str.c_str());}};
typedef long long ll;
typedef unsigned long long ull;
#define PII pair<int,int>
#define PLL pair<ll,ll>
const int INF=0x3f3f3f3f;
const ll LLINF=0x3f3f3f3f3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-8;
const int MAX=2e5+10;
const ll mod=1e9+7;
int sgn(double x)
{
    if(fabs(x)<eps) return 0;
    if(x<0) return -1;
    return 1;
}
struct Point
{
    double x,y;
    Point() {}
    Point(double x_,double y_):x(x_),y(y_) {}
    Point operator -(const Point &t)
    {
        return Point(x-t.x,y-t.y);
    }
    Point operator +(const Point &t)
    {
        return Point(x+t.x,y+t.y);
    }
    double operator *(const Point &t)
    {
        return x*t.x+y*t.y;
    }
    Point operator *(double t)
    {
        return Point(x*t,y*t);
    }
    double operator ^(const Point &t)
    {
        return x*t.y-y*t.x;
    }
    double friend dist(const Point &a,const Point &b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    void input()
    {
        scanf("%lf%lf",&x,&y);
    }
} p[15];
int n;
double R;
namespace SK
{
bool inCircle(Point &cir,Point &a)
{
    return sgn(dist(cir,a)-R)<=0;
}
double triArea2(Point &a,Point &b,Point &c)
{
    return fabs((b-a)^(c-a));
}
bool sameSide(Point &cir,Point &a,Point &b)
{
    if(dist(a,cir)>dist(b,cir)) return sgn((a-b)*(cir-b))<=0;
    else return sgn((b-a)*(cir-a))<=0;
}
double calc(Point &cir,Point a,Point b)
{
    double xmulti=(a-cir)^(b-cir);
    if(sgn(xmulti)==0) return 0;
    double ans=0;
    double theta=acos(((a-cir)*(b-cir))/(dist(a,cir)*dist(b,cir)));
    double h=triArea2(cir,a,b)/dist(a,b);
    bool ina=inCircle(cir,a),inb=inCircle(cir,b);
    if(ina && inb) ans=triArea2(cir,a,b)/2;
    else if(!ina && !inb)
    {
        if(sameSide(cir,a,b)) ans=R*R*theta/2;
        else if(sgn(h-R)>=0) ans=R*R*theta/2;
        else
        {
            double theta2=2*acos(h/R);
            ans=R*R*(theta-theta2+sin(theta2))/2;
        }
    }
    else
    {
        if(!ina && inb) swap(a,b);
        double tem=(cir-a)*(b-a);
        if(sgn(tem)==0)
        {
            double alpha=acos(h/R);
            ans=R*h/2*sin(alpha)+R*R*(theta-alpha)/2;
        }
        else
        {
            double theta1=asin(h/R),theta2=asin(h/dist(a,cir));
            if(sgn(tem)>0)
            {
                ans+=dist(cir,a)*R/2*sin(PI-theta1-theta2);
                ans+=R*R/2*(theta+theta1+theta2-PI);
            }
            else
            {
                ans+=dist(cir,a)*R/2*sin(theta2-theta1);
                ans+=R*R/2*(theta-theta2+theta1);
            }
        }
    }
    if(sgn(xmulti)<0) return -ans;
    else return ans;
}
double coArea(Point &cir)
{
    double ans=0;
    for(int i=0; i<n; ++i)
        ans+=calc(cir,p[i],p[i+1]);
    return fabs(ans);
}
}
pair<Point,double> SA()
{  
	Point s;  
	double T=100,t,ds,dz,ans;  
	int i,j,k,flag,dir[5][2]={0,0,1,0,-1,1,0,-1,0};
	s=Point(0,0);
	for(i=0;i<n;i++)
	{  
		s.x+=p[i].x;  
		s.y+=p[i].y;  
	}
	s.x/=n;  
	s.y/=n;  
	ans=0;
	for(k=1;k<=100000;k++)
	{
		t=T/k;
		for(i=0;i<5;i++)  
		{
			Point z;
			z.x=s.x+dir[i][0]*t;  
			z.y=s.y+dir[i][1]*t;  
			dz=SK::coArea(z);
			if(dz>ans)  
			{  
				ans=dz;
				s=z;
			} 
		}
	}
	pair<Point,double> res;
	res=make_pair(s,ans);
	return res;
}
int main()
{
	int i;
	while(~scanf("%d%lf",&n,&R))
	{
		for(i=0;i<n;i++)
		{
			p[i].input();
		}
		p[n]=p[0];
	//	printf("%.6lf\n",getres(Point(3,3),p,n+1));
		pair<Point,double> ans=SA();
		printf("%.8lf\n",ans.se);
	}
	return 0;
}
accuracy: 0.5370370370370371
time_ms: 460
memory_kb: 3692
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define mem(a,b) memset((a),(b),sizeof(a))
#define MP make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) x.size()
#define all(x) x.begin(),x.end()
using namespace std;
#define _GLIBCXX_PERMIT_BACKWARD_HASH
#include <ext/hash_map>
using namespace __gnu_cxx;
struct str_hash{size_t operator()(const string& str)const{return __stl_hash_string(str.c_str());}};
typedef long long ll;
typedef unsigned long long ull;
#define PII pair<int,int>
#define PLL pair<ll,ll>
const int INF=0x3f3f3f3f;
const ll LLINF=0x3f3f3f3f3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-8;
const int MAX=2e5+10;
const ll mod=1e9+7;
int sgn(double x)
{
    if(fabs(x)<eps) return 0;
    if(x<0) return -1;
    return 1;
}
struct Point
{
    double x,y;
    Point() {}
    Point(double x_,double y_):x(x_),y(y_) {}
    Point operator -(const Point &t)
    {
        return Point(x-t.x,y-t.y);
    }
    Point operator +(const Point &t)
    {
        return Point(x+t.x,y+t.y);
    }
    double operator *(const Point &t)
    {
        return x*t.x+y*t.y;
    }
    Point operator *(double t)
    {
        return Point(x*t,y*t);
    }
    double operator ^(const Point &t)
    {
        return x*t.y-y*t.x;
    }
    double friend dist(const Point &a,const Point &b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    void input()
    {
        scanf("%lf%lf",&x,&y);
    }
} p[15];
int n;
double R;
namespace SK
{
bool inCircle(Point &cir,Point &a)
{
    return sgn(dist(cir,a)-R)<=0;
}
double triArea2(Point &a,Point &b,Point &c)
{
    return fabs((b-a)^(c-a));
}
bool sameSide(Point &cir,Point &a,Point &b)
{
    if(dist(a,cir)>dist(b,cir)) return sgn((a-b)*(cir-b))<=0;
    else return sgn((b-a)*(cir-a))<=0;
}
double calc(Point &cir,Point a,Point b)
{
    double xmulti=(a-cir)^(b-cir);
    if(sgn(xmulti)==0) return 0;
    double ans=0;
    double theta=acos(((a-cir)*(b-cir))/(dist(a,cir)*dist(b,cir)));
    double h=triArea2(cir,a,b)/dist(a,b);
    bool ina=inCircle(cir,a),inb=inCircle(cir,b);
    if(ina && inb) ans=triArea2(cir,a,b)/2;
    else if(!ina && !inb)
    {
        if(sameSide(cir,a,b)) ans=R*R*theta/2;
        else if(sgn(h-R)>=0) ans=R*R*theta/2;
        else
        {
            double theta2=2*acos(h/R);
            ans=R*R*(theta-theta2+sin(theta2))/2;
        }
    }
    else
    {
        if(!ina && inb) swap(a,b);
        double tem=(cir-a)*(b-a);
        if(sgn(tem)==0)
        {
            double alpha=acos(h/R);
            ans=R*h/2*sin(alpha)+R*R*(theta-alpha)/2;
        }
        else
        {
            double theta1=asin(h/R),theta2=asin(h/dist(a,cir));
            if(sgn(tem)>0)
            {
                ans+=dist(cir,a)*R/2*sin(PI-theta1-theta2);
                ans+=R*R/2*(theta+theta1+theta2-PI);
            }
            else
            {
                ans+=dist(cir,a)*R/2*sin(theta2-theta1);
                ans+=R*R/2*(theta-theta2+theta1);
            }
        }
    }
    if(sgn(xmulti)<0) return -ans;
    else return ans;
}
double coArea(Point &cir)
{
    double ans=0;
    for(int i=0; i<n; ++i)
        ans+=calc(cir,p[i],p[i+1]);
    return fabs(ans);
}
}
pair<Point,double> SA()
{  
	Point s;  
	double T=100,t,ds,dz,ans;  
	int i,j,k,flag,dir[5][2]={0,0,1,0,-1,1,0,-1,0};
	s=Point(0,0);
	for(i=0;i<n;i++)
	{  
		s.x+=p[i].x;  
		s.y+=p[i].y;  
	}
	s.x/=n;  
	s.y/=n;  
	ans=0;
	for(k=1;k<=100000;k++)
	{
		t=T/k;
		for(i=0;i<5;i++)  
		{
			Point z;
			z.x=s.x+dir[i][0]*t;  
			z.y=s.y+dir[i][1]*t;  
			dz=SK::coArea(z);
			if(dz>ans)  
			{  
				ans=dz;
				s=z;
			} 
		}
	}
	pair<Point,double> res;
	res=make_pair(s,ans);
	return res;
}
int main()
{
	int i;
	while(~scanf("%d%lf",&n,&R))
	{
		for(i=0;i<n;i++)
		{
			p[i].input();
		}
		p[n]=p[0];
	//	printf("%.6lf\n",getres(Point(3,3),p,n+1));
		pair<Point,double> ans=SA();
		printf("%.6lf\n",ans.se);
	}
	return 0;
}
accuracy: 0.5370370370370371
time_ms: 480
memory_kb: 3692
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define mem(a,b) memset((a),(b),sizeof(a))
#define MP make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) x.size()
#define all(x) x.begin(),x.end()
using namespace std;
#define _GLIBCXX_PERMIT_BACKWARD_HASH
#include <ext/hash_map>
using namespace __gnu_cxx;
struct str_hash{size_t operator()(const string& str)const{return __stl_hash_string(str.c_str());}};
typedef long long ll;
typedef unsigned long long ull;
#define PII pair<int,int>
#define PLL pair<ll,ll>
const int INF=0x3f3f3f3f;
const ll LLINF=0x3f3f3f3f3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-8;
const int MAX=2e5+10;
const ll mod=1e9+7;
double r;
int sgn(double x)
{  
	if(fabs(x)<eps) return 0;
	else return x>0?1:-1;  
}
struct Point
{  
	double x,y;
	Point(){}
	Point(double a,double b)
	{
		x=a;
		y=b;
	}
	void input()
	{
		scanf("%lf%lf",&x,&y);
	}
};
typedef Point Vector;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}  
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}  
Vector operator *(Vector a,double p){return Vector(a.x*p,a.y*p);}  
Vector operator /(Vector a,double p){return Vector(a.x/p,a.y/p);}

bool operator <(Point a,Point b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool operator ==(Point a,Point b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}
double dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//点?
double length(Vector a){return sqrt(dot(a,a));}//向量的模 

double cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}//叉? 
double dist(Point a,Point b){return sqrt(dot(a-b,a-b));}//?点距? 
Point midseg(Point a,Point b){return (a+b)/2;}//?段ab中点
Vector Normal(Vector x){return Point(-x.y,x.x)/length(x);} //垂直法向量 
Vector Rotate(Vector a, double rad){return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));}
double calarea(Point c,Point b,Point a){return cross(b-a,c-a);}//三个点求三角形面? 
Vector vecunit(Vector x){return x/length(x);}//?位向量
double VectorAngle(Vector v){return atan2(v.y,v.x);}
struct Line
{  
	Point p;//直?上任意一点  
	Vector v;//?角,即从x正半?旋?到向量v所需要的角（弧度）  
	double ang;
	double a,b,c;//直?一般式 
	Line(){}
	Line(Point a,Vector b)//点斜式 
	{
		p=a;
		v=b;
		ang=atan2(v.y,v.x);
		LineGeneralEquation();
	}
	void twopoint(Point a,Point b)//?点式 
	{
		p=a;
		v=b-a;
		ang=atan2(v.y,v.x);
		LineGeneralEquation();
	}
	Point getpoint(double a)
	{  
		return p+(v*a);  
	}
	void LineGeneralEquation()//?算一般式的a,b,c 
	{
		Point p1,p2;
		p1=p;
		p2=p+v;
		a=p2.y-p1.y;  
		b=p1.x-p2.x;  
		c=-a*p1.x-b*p1.y;
	}
};
struct Circle  
{  
    Point c;  
    double r;  
    Circle(){}  
    Circle(Point a,double b)
    {
		c=a;
		r=b;
	}
	Point getpoint(double a) //根据?心角求点坐?  
	{  
        return Point(c.x+cos(a)*r,c.y+sin(a)*r);  
	}  
}; 
bool OnSeg(Point p,Point p1,Point p2)
{  
	return sgn(cross(p1-p,p2-p))==0&&sgn(dot(p1-p,p2-p))<0;
}
Point PointOfLineInter(Line a,Line b)//?段交点
{
	Vector u=a.p-b.p;
	double t=cross(b.v,u)/cross(a.v,b.v);
	return a.p+a.v*t;
}
bool InCircle(Point x,Circle c){return sgn(c.r-length(c.c-x))>=0;}//在?内(包括?上) 
int getSegCircleInter(Line l,Circle c,Point *sol)//?段与?的交点
{  
	Vector nor=Normal(l.v);
	Line l1=Line(c.c,nor);  
	Point p1=PointOfLineInter(l1,l);  
	double d=length(p1-c.c);  
    if(sgn(d-c.r)>0) return 0;
	Point p2=vecunit(l.v)*sqrt(c.r*c.r-d*d);  
	int res=0;  
	sol[res]=p1+p2;  
    if(OnSeg(sol[res],l.p,l.getpoint(1))) res++;
	sol[res]=p1-p2;
	if(OnSeg(sol[res],l.p,l.getpoint(1))) res++;  
	return res;  
}  
double SegCircleArea(Circle c,Point a,Point b) //?段切割?  
{  
	double a1=VectorAngle(a-c.c);  
	double a2=VectorAngle(b-c.c);  
	double da=fabs(a1-a2);  
	if (sgn(da-PI)>0) da=PI*2.0-da;  
	return sgn(cross(b-c.c,a-c.c))*da*c.r*c.r/2.0;  
}
double PolyCiclrArea(Circle c,Point *p,int n)//多?形与?面?交  
{  
	double res=0;  
	Point sol[2];  
	for(int i=0;i<n;i++)
	{
		double t1,t2;  
		int cnt=getSegCircleInter(Line(p[i],p[i+1]-p[i]),c,sol);  
		if(cnt==0)  
		{  
			if(!InCircle(p[i],c)||!InCircle(p[i+1],c)) res+=SegCircleArea(c,p[i],p[i+1]);  
			else res+=cross(p[i+1]-c.c,p[i]-c.c)/2.0;  
		}  
		if(cnt==1)  
		{  
			if(InCircle(p[i],c)&&!InCircle(p[i+1],c))
			{
				res+=cross(sol[0]-c.c,p[i]-c.c)/2.0;
				res+=SegCircleArea(c,sol[0],p[i+1]);  
			}
			else
			{
				res+=SegCircleArea(c,p[i],sol[0]);
				res+=cross(p[i+1]-c.c,sol[0]-c.c)/2.0;  
			}
		}  
		if(cnt==2)  
		{  
			if((p[i]<p[i+1])^(sol[0]<sol[1])) swap(sol[0],sol[1]);  
			res+=SegCircleArea(c,p[i],sol[0]);  
			res+=cross(sol[1]-c.c,sol[0]-c.c)/2.0;  
			res+=SegCircleArea(c,sol[1],p[i+1]);  
		}  
	}  
	return fabs(res);  
}
double getres(Point t,Point *p,int n)
{
	double res=0;
	res=PolyCiclrArea(Circle(t,r),p,n);
	return res;
}
pair<Point,double> SA(Point *p,int n)
{  
	Point s;  
	double t=0,ds,dz,ans;  
	int i,j,k,flag,dir[4][2]={0,1,0,-1,1,0,-1,0};
	s=Point(0,0);
	for(i=0;i<n;i++)
	{  
		t+=fabs(p[i].x)+fabs(p[i].y);  
		s.x+=p[i].x;  
		s.y+=p[i].y;  
	}
	s.x/=n;  
	s.y/=n;  
	t=100;
	ans=0;
	while(t>1e-20)  
	{  
		t/=2;
		for(k=0;k<1000;k++)
		{
			for(i=0;i<4;i++)  
			{
				Point z;
				z.x=s.x+dir[i][0]*t;  
				z.y=s.y+dir[i][1]*t;  
				ds=dz=0;  
				dz=getres(z,p,n);
				if(dz>ans)  
				{  
					s=z;
					ans=dz;
				} 
			}
		}
	}  
	pair<Point,double> res;
	res=make_pair(s,ans);
	return res;
}
int main()
{
	int n,i;
	Point p[12];
	while(~scanf("%d%lf",&n,&r))
	{
		for(i=0;i<n;i++)
		{
			p[i].input();
		}
		p[n]=p[0];
	//	printf("%.6lf\n",getres(Point(3,3),p,n+1));
		pair<Point,double> ans=SA(p,n);
		printf("%.6lf\n",ans.se);
	}
	return 0;
}
accuracy: 0.09259259259259259
time_ms: 330
memory_kb: 3520
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define mem(a,b) memset((a),(b),sizeof(a))
#define MP make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) x.size()
#define all(x) x.begin(),x.end()
using namespace std;
#define _GLIBCXX_PERMIT_BACKWARD_HASH
#include <ext/hash_map>
using namespace __gnu_cxx;
struct str_hash{size_t operator()(const string& str)const{return __stl_hash_string(str.c_str());}};
typedef long long ll;
typedef unsigned long long ull;
#define PII pair<int,int>
#define PLL pair<ll,ll>
const int INF=0x3f3f3f3f;
const ll LLINF=0x3f3f3f3f3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-8;
const int MAX=2e5+10;
const ll mod=1e9+7;
double r;
int sgn(double x)
{  
	if(fabs(x)<eps) return 0;
	else return x>0?1:-1;  
}
struct Point
{  
	double x,y;
	Point(){}
	Point(double a,double b)
	{
		x=a;
		y=b;
	}
	void input()
	{
		scanf("%lf%lf",&x,&y);
	}
};
typedef Point Vector;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}  
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}  
Vector operator *(Vector a,double p){return Vector(a.x*p,a.y*p);}  
Vector operator /(Vector a,double p){return Vector(a.x/p,a.y/p);}

bool operator <(Point a,Point b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool operator ==(Point a,Point b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}
double dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//点?
double length(Vector a){return sqrt(dot(a,a));}//向量的模 

double cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}//叉? 
double dist(Point a,Point b){return sqrt(dot(a-b,a-b));}//?点距? 
Point midseg(Point a,Point b){return (a+b)/2;}//?段ab中点
Vector Normal(Vector x){return Point(-x.y,x.x)/length(x);} //垂直法向量 
Vector Rotate(Vector a, double rad){return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));}
double calarea(Point c,Point b,Point a){return cross(b-a,c-a);}//三个点求三角形面? 
Vector vecunit(Vector x){return x/length(x);}//?位向量
double VectorAngle(Vector v){return atan2(v.y,v.x);}
struct Line
{  
	Point p;//直?上任意一点  
	Vector v;//?角,即从x正半?旋?到向量v所需要的角（弧度）  
	double ang;
	double a,b,c;//直?一般式 
	Line(){}
	Line(Point a,Vector b)//点斜式 
	{
		p=a;
		v=b;
		ang=atan2(v.y,v.x);
		LineGeneralEquation();
	}
	void twopoint(Point a,Point b)//?点式 
	{
		p=a;
		v=b-a;
		ang=atan2(v.y,v.x);
		LineGeneralEquation();
	}
	Point getpoint(double a)
	{  
		return p+(v*a);  
	}
	void LineGeneralEquation()//?算一般式的a,b,c 
	{
		Point p1,p2;
		p1=p;
		p2=p+v;
		a=p2.y-p1.y;  
		b=p1.x-p2.x;  
		c=-a*p1.x-b*p1.y;
	}
};
struct Circle  
{  
    Point c;  
    double r;  
    Circle(){}  
    Circle(Point a,double b)
    {
		c=a;
		r=b;
	}
	Point getpoint(double a) //根据?心角求点坐?  
	{  
        return Point(c.x+cos(a)*r,c.y+sin(a)*r);  
	}  
}; 
bool OnSeg(Point p,Point p1,Point p2)
{  
	return sgn(cross(p1-p,p2-p))==0&&sgn(dot(p1-p,p2-p))<0;
}
Point PointOfLineInter(Line a,Line b)//?段交点
{
	Vector u=a.p-b.p;
	double t=cross(b.v,u)/cross(a.v,b.v);
	return a.p+a.v*t;
}
bool InCircle(Point x,Circle c){return sgn(c.r-length(c.c-x))>=0;}//在?内(包括?上) 
int getSegCircleInter(Line l,Circle c,Point *sol)//?段与?的交点
{  
	Vector nor=Normal(l.v);
	Line l1=Line(c.c,nor);  
	Point p1=PointOfLineInter(l1,l);  
	double d=length(p1-c.c);  
    if(sgn(d-c.r)>0) return 0;
	Point p2=vecunit(l.v)*sqrt(c.r*c.r-d*d);  
	int res=0;  
	sol[res]=p1+p2;  
    if(OnSeg(sol[res],l.p,l.getpoint(1))) res++;
	sol[res]=p1-p2;
	if(OnSeg(sol[res],l.p,l.getpoint(1))) res++;  
	return res;  
}  
double SegCircleArea(Circle c,Point a,Point b) //?段切割?  
{  
	double a1=VectorAngle(a-c.c);  
	double a2=VectorAngle(b-c.c);  
	double da=fabs(a1-a2);  
	if (sgn(da-PI)>0) da=PI*2.0-da;  
	return sgn(cross(b-c.c,a-c.c))*da*c.r*c.r/2.0;  
}
double PolyCiclrArea(Circle c,Point *p,int n)//多?形与?面?交  
{  
	double res=0;  
	Point sol[2];  
	for(int i=0;i<n;i++)
	{
		double t1,t2;  
		int cnt=getSegCircleInter(Line(p[i],p[i+1]-p[i]),c,sol);  
		if(cnt==0)  
		{  
			if(!InCircle(p[i],c)||!InCircle(p[i+1],c)) res+=SegCircleArea(c,p[i],p[i+1]);  
			else res+=cross(p[i+1]-c.c,p[i]-c.c)/2.0;  
		}  
		if(cnt==1)  
		{  
			if(InCircle(p[i],c)&&!InCircle(p[i+1],c))
			{
				res+=cross(sol[0]-c.c,p[i]-c.c)/2.0;
				res+=SegCircleArea(c,sol[0],p[i+1]);  
			}
			else
			{
				res+=SegCircleArea(c,p[i],sol[0]);
				res+=cross(p[i+1]-c.c,sol[0]-c.c)/2.0;  
			}
		}  
		if(cnt==2)  
		{  
			if((p[i]<p[i+1])^(sol[0]<sol[1])) swap(sol[0],sol[1]);  
			res+=SegCircleArea(c,p[i],sol[0]);  
			res+=cross(sol[1]-c.c,sol[0]-c.c)/2.0;  
			res+=SegCircleArea(c,sol[1],p[i+1]);  
		}  
	}  
	return fabs(res);  
}
double getres(Point t,Point *p,int n)
{
	double res=0;
	res=PolyCiclrArea(Circle(t,r),p,n);
	return res;
}
pair<Point,double> SA(Point *p,int n)
{  
	Point s;  
	double T=100,t,ds,dz,ans;  
	int i,j,k,flag,dir[5][2]={0,0,1,0,-1,1,0,-1,0};
	s=Point(0,0);
	for(i=0;i<n;i++)
	{  
		s.x+=p[i].x;  
		s.y+=p[i].y;  
	}
	s.x/=n;  
	s.y/=n;  
	ans=0;
	for(k=1;k<=200000;k++)
	{
		t=T/k;
		for(i=0;i<5;i++)  
		{
			Point z;
			z.x=s.x+dir[i][0]*t;  
			z.y=s.y+dir[i][1]*t;  
			dz=getres(z,p,n);
			if(dz>ans)  
			{  
				ans=dz;
				s=z;
			} 
		}
	}
	pair<Point,double> res;
	res=make_pair(s,ans);
	return res;
}
int main()
{
	int n,i;
	Point p[12];
	while(~scanf("%d%lf",&n,&r))
	{
		for(i=0;i<n;i++)
		{
			p[i].input();
		}
		p[n]=p[0];
	//	printf("%.6lf\n",getres(Point(3,3),p,n+1));
		pair<Point,double> ans=SA(p,n);
		printf("%.6lf\n",ans.se);
	}
	return 0;
}
accuracy: 0.09259259259259259
time_ms: 1120
memory_kb: 3456
final_rank: 19