← Home
#include <bits/stdc++.h>
using namespace std;
 
const double PI12 = 1.57079632679489661923;
 
struct Point {
    double x, y;
 
    Point(double x = 0, double y = 0) : x(x), y(y) {}
 
    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
 
    double crossP(const Point& p) const { return x * p.y - y * p.x; }
 
    double crossP(const Point& p1, const Point& p2) const {
        return (p1.x - x) * (p2.y - y) - (p1.y - y) * (p2.x - x);
    }
 
    double dotP(const Point& p) const { return x * p.x + y * p.y; }
 
    double dist(const Point& p) const {
        Point t = p - *this;
        return sqrt(t.x * t.x + t.y * t.y);
    }
 
    double dist2(const Point& p) const {
        Point t = p - *this;
        return t.x * t.x + t.y * t.y;
    }
 
    bool crossLines(const Point& p1, const Point& p2, const Point& p3, const Point& p4) {
        Point d12 = p1 - p2, d34 = p3 - p4;
        double den = d12.crossP(d34);
        if (abs(den) < 1e-7) return false;
        x = (p1.crossP(p2) * d34.x - d12.x * p3.crossP(p4)) / den;
        y = (p1.crossP(p2) * d34.y - d12.y * p3.crossP(p4)) / den;
        return true;
    }
 
    int quadrant() const { return signbit(x) ^ signbit(y) * 3; }
 
    int quaT(const Point& p, double t) const {
        int k = p.quadrant() - quadrant();
        if (k < 0) k += 4;
        k -= (k & 1) ^ signbit(t);
        return (k < 0) ? k = 3 : k;
    }
};
 
vector<Point> poly;
int n;
 
Point& getP(int i) {
    if (i < 0) return poly[n - 1];
    if (i >= n) return poly[0];
    return poly[i];
}
 
double sectE(const Point& v0, const Point& v1, double ab) {
    double ta = v0.crossP(v1) / v0.dotP(v1) * ab;
    int k = v0.quaT(v1, ta);
    if (ta < 0) ta = -1.0 / ta;
    return atan(ta) + k * PI12;
}
 
double segArea(const Point& f1, const Point& f2, const Point& v1, const Point& v2, double r) {
    Point v0((f1.x + f2.x) / 2.0, (f1.y + f2.y) / 2.0);
    double dx = f1.x - v0.x, dy = f1.y - v0.y;
    double a = r / 2.0, b = sqrt(a * a - dx * dx - dy * dy);
    dx = a / b;
    return a * b * (sectE(f1 - v0, v2 - v0, dx) - sectE(f1 - v0, v1 - v0, dx)) - v0.crossP(v1, v2);
}
 
double root2(double x3, double y3, double dx, double k, double r) {
    double r2 = r * r, cdk = x3 + y3 * k, k21 = k * k + 1, d = r * sqrt(k21);
    double m = (x3 * x3 + y3 * y3 - r2) / (2.0 * (cdk * cdk - r2 * k21));
    double x = m * (cdk + d);
    if (signbit(x) != signbit(dx)) x = m * (cdk - d);
    return x;
}
 
Point archPoint2(const Point& p1, const Point& p2, const Point& p3, double r) {
    double x, y;
    Point d32 = p3 - p2, d21 = p2 - p1;
    if (abs(d21.x) > abs(d21.y)) {
        double k = d21.y / d21.x;
        x = root2(d32.x, d32.y, d21.x, k, r);
        y = p2.y + k * x;
        x += p2.x;
    } else {
        double k = d21.x / d21.y;
        y = root2(d32.y, d32.x, d21.y, k, r);
        x = p2.x + k * y;
        y += p2.y;
    }
    return Point(x, y);
}
 
void solve() {
    double remStr;
    cin >> n >> remStr;
    poly.resize(n);
 
    for (int i = 0; i < n; i++) {
        cin >> poly[i].x >> poly[i].y;
        if (i > 1) remStr -= poly[i - 1].dist(poly[i]);
    }
    remStr -= poly[n - 1].dist(poly[0]);
 
    int pf1 = 0, pf2 = 0;
    double pr = 0, areaFS = 0;
    Point v0, pv;
    bool pull = true;
 
    for (int i = 0, j = 1, k = 0; i < n;) {
        if (j == n) j = 0;
        if (pull) {
            pull = false;
            Point p;
            if (p.crossLines(getP(i - 1), getP(i), getP(j), getP(j + 1))) {
                if (getP(i).crossP(p, getP(i + 1)) > 0) {
                    double d1 = p.dist2(getP(i)), d2 = p.dist2(getP(j));
                    double rem = remStr * remStr - d1 - d2;
                    if (rem > 0 && rem * rem - 4 * d1 * d2 > 0) {
                        remStr += getP(j).dist(getP(j + 1));
                        j++;
                        pull = true;
                        continue;
                    }
                }
            }
            p = archPoint2(getP(i - 1), getP(i), getP(j), remStr);
            if (k == 0) v0 = p;
            if (k > 0) areaFS += segArea(getP(pf1), getP(pf2), pv, p, pr);
            if (k > 1) areaFS += v0.crossP(pv, p);
            pv = p;
            pf1 = i; pf2 = j; pr = remStr;
            k++;
        }
        Point p = archPoint2(getP(j + 1), getP(j), getP(i), remStr);
        if (getP(i).crossP(p, getP(i + 1)) < 0) {
            remStr -= getP(i).dist(getP(i + 1));
            i++;
            pull = true;
            continue;
        }
        areaFS += segArea(getP(pf1), getP(pf2), pv, p, pr);
        if (k > 1) areaFS += v0.crossP(pv, p);
        pv = p;
        pf1 = i;
        pf2 = (j + 1 < n) ? (j + 1) : 0;
        remStr += getP(j).dist(getP(j + 1));
        j++; pr = remStr;
        k++;
    }
    areaFS += segArea(getP(pf1), getP(pf2), pv, v0, pr);
    cout << setprecision(16) << areaFS / 2 << endl;
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();
    return 0;
}