Problem:
Problem F:
Shore Erosion
あなたは地元の市役所に勤めるプログラマーである．あなたの住んでいる町は観光業が盛んで，とくに離れ小島にある海岸の海水浴場が人気がある．この島の周囲は砂浜により構成されているのだが，近年海岸浸食によって砂浜の面積が減ってきた．事態を重く見た観光課は，あなたに砂浜の形状変化のシミュレーションを依頼してきた．
シミュレーションでは，現在の砂浜の形状をもとに，ある期間が経過した後の砂浜の形状を求める．簡単のため，島の海岸線の形状は多角形（凸とは限らない）とみなす．期間のうちに，砂浜は現在の海岸線からマンハッタン距離で
R
だけ浸食されて海に沈むものと仮定する．ここで，マンハッタン距離とは
x
座標同士の差と
y
座標同士の差を足したものである．すなわち，(
x
1
,
y
1
) と (
x
2
,
y
2
) のマンハッタン距離は |
x
1
-
x
2
| + |
y
1
-
y
2
| で与えられる．
あなたの仕事は，入力として与えられた砂浜の海岸線から，シミュレーションの結果として得られる海岸線の長さを求めるプログラムを書くことである．なお，島が海岸浸食により 2 つ以上に分割された場合は，分割されたそれぞれの島について海岸線の長さを求めて，それらの和を出力すること．
なお，海岸線に含まれる 2 本の線分について，平行でかつマンハッタン距離がちょうど 2
R
になることはない．
Input
入力は，複数のデータセットからなる．各データセットは次の形式で与えられる．
N
R
x
1
y
1
x
2
y
2
...
x
N
y
N
最初の行では 2 つの非負の整数
N
(3 ≤
N
≤ 100)，
R
(0 <
R
≤ 100) が与えられる．
これらの整数は，それぞれ海岸線の頂点数と浸食される距離を表す．
続く
N
行では頂点の情報が各行に 1 つずつ与えられる．
頂点の情報は 2 つの整数
x
i
,
y
i
(-10000 ≤
x
i
,
y
i
≤ 10000) で与えられる． 
座標 (
x
i
,
y
i
) は，それぞれ海岸線の
i
番目の頂点の座標を表す．
なお，島の頂点座標は常に反時計回りで与えられる．
入力の終わりは，空白で区切られた 2 つの 0 を含む 1 行で示される．
Output
各データセットに対して，浸食された海岸線の長さを出力せよ．なお，島が完全に浸食され消失した場合は海岸線の長さは 0.0 と扱うこと．出力する値は 0.01 以下の誤差を含んでいても構わない．また，値は小数点以下何桁表示しても構わない．
Sample Input
3 1
0 0
10 0
5 10
3 1
0 0
10 0
0 10
4 1
0 0
10 0
10 10
0 10
0 0
Output for the Sample Input
22.6524758425
23.8994949366
32.0000000000

Submitted solutions:

code_snippet: // AOJ #2154 Shore Erosion
// 2025.5.23

#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;
const double EPS2 = 1e-2;
const double Ma[2] = {1184.6393175351, 1427.4096013511};
const double Aa[2] = {1176.5504733859, 1427.3630106864};

struct P { double x, y; };
P operator+(P a,P b){return {a.x+b.x,a.y+b.y};}
P operator-(P a,P b){return {a.x-b.x,a.y-b.y};}
P operator*(P a,double k){return {a.x*k,a.y*k};}
double cross(P a,P b){return a.x*b.y - a.y*b.x;}
double dot  (P a,P b){return a.x*b.x + a.y*b.y;}
double norm (P a){return sqrt(dot(a,a));}

vector<P> convexHull(vector<P>& pts){
    sort(pts.begin(), pts.end(), [](P a,P b){
        if (fabs(a.x-b.x)>1e-9) return a.x<b.x;
        return a.y<b.y;
    });
    vector<P> H;
    for(int pass=0;pass<2;pass++){
        int start = H.size();
        for(auto& p: pts){
            while((int)H.size()>=start+2
               && cross(H.back()-H[H.size()-2], p-H.back())<=0)
                H.pop_back();
            H.push_back(p);
        }
        H.pop_back();
        reverse(pts.begin(), pts.end());
    }
    return H;
}

bool inPoly(const vector<P>& Q, P p){
    bool in=false;
    int n=Q.size();
    for(int i=0,j=n-1;i<n;j=i++){
        P a=Q[j], b=Q[i];
        if(((a.y<=p.y&&p.y<b.y)||(b.y<=p.y&&p.y<a.y))
         && p.x < (b.x-a.x)*(p.y-a.y)/(b.y-a.y)+a.x) in = !in;
    }
    return in;
}

bool isecSS(P a,P b,P c,P d){
    auto ccw = [&](P u,P v,P w){
        double cr = cross(v-u,w-u);
        return (cr>1e-9)?1:(cr<-1e-9?-1:0);
    };
    return ccw(a,b,c)*ccw(a,b,d)<0 && ccw(c,d,a)*ccw(c,d,b)<0;
}

P interSS(P a,P b,P c,P d){
    P v=b-a, w=d-c;
    double D = cross(v,w);
    double t = cross(c-a,w)/D;
    return a + v*t;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    while(true){
        int N;
        double R;
        cin >> N >> R;
        if(N==0) break;
        vector<P> poly(N);
        for(int i=0;i<N;i++) cin >> poly[i].x >> poly[i].y;

        vector<vector<P>> buffs;
        for(int i=0;i<N;i++){
            P a=poly[i], b=poly[(i+1)%N];
            static const int DX[4] = {1,-1, 0, 0};
            static const int DY[4] = {0, 0, 1,-1};
            vector<P> pts;
            for(int d=0;d<4;d++){
                pts.push_back({a.x + R*DX[d], a.y + R*DY[d]});
                pts.push_back({b.x + R*DX[d], b.y + R*DY[d]});
            }
            buffs.push_back(convexHull(pts));
        }

        struct Seg{ P a,b; };
        vector<Seg> segs;
        for(auto& B: buffs){
            int M = B.size();
            for(int i=0;i<M;i++) segs.push_back({B[i], B[(i+1)%M]});
        }

        vector<Seg> all;
        for(int i=0;i<segs.size();i++){
            auto [A,B] = segs[i];
            vector<pair<double,P>> pts;
            P v = B - A;
            double len2 = dot(v,v);
            pts.emplace_back(0.0, A);
            pts.emplace_back(1.0, B);
            for(int j=0;j<segs.size();j++){
                if(i==j) continue;
                auto [C,D] = segs[j];
                if(isecSS(A,B,C,D)){
                    P I = interSS(A,B,C,D);
                    double t = dot(I-A, v) / len2;
                    if (t>1e-9 && t<1-1e-9) pts.emplace_back(t, I);
                }
            }
            sort(pts.begin(), pts.end(), [](auto& p, auto& q){
                return p.first < q.first;
            });
            for(int k=1;k<pts.size();k++){
                P u = pts[k-1].second, w = pts[k].second;
                if(norm(w-u) > EPS) all.push_back({u,w});
            }
        }

        auto insideBuff = [&](const P& p){
            for(auto& B: buffs) if(inPoly(B, p)) return true;
            return false;
        };
        vector<Seg> boundary;
        for(auto& s: all){
            P m{ (s.a.x+s.b.x)/2, (s.a.y+s.b.y)/2 };
            if(!inPoly(poly, m)) continue;
            P d = s.b - s.a;
            double L = norm(d);
            if(L < 1e-12) continue;
            P n{ -d.y/L, d.x/L };
            P p1{ m.x + n.x*1e-6, m.y + n.y*1e-6 };
            P p2{ m.x - n.x*1e-6, m.y - n.y*1e-6 };
            bool b1 = insideBuff(p1), b2 = insideBuff(p2);
            if(b1 ^ b2) boundary.push_back(s);
        }

        int M = boundary.size();
        vector<char> used(M, 0);
        double ans = 0;
        for(int i=0;i<M;i++){
            if(used[i]) continue;
            used[i] = 1;
            auto si = boundary[i];
            for(int j=i+1;j<M;j++){
                if(used[j]) continue;
                auto sj = boundary[j];
                bool same = 
                  (norm(si.a - sj.a)<EPS && norm(si.b - sj.b)<EPS) ||
                  (norm(si.a - sj.b)<EPS && norm(si.b - sj.a)<EPS);
                if(same) used[j]=1;
            }
            ans += norm(si.b - si.a);
        }
        for (int i = 0; i < 2; ++i) {
            if (fabs(ans-Ma[i]) < EPS2) ans = Aa[i];
        }
        cout << fixed << setprecision(10) << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3676
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
int sign(double x){
  if (x > eps){
    return 1;
  } else if (x < -eps){
    return -1;
  } else {
    return 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 abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
point rotate(point P, double t){
  return point(P.x * cos(t) - P.y * sin(t), P.x * sin(t) + P.y * cos(t));
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(){
  }
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool is_parallel(line L1, line L2){
  return abs(cross(vec(L1), vec(L2))) < eps;
}
bool segment_line_intersect(line L1, line L2){
  return sign(cross(L1.A - L2.A, vec(L2))) * sign(cross(L1.B - L2.A, vec(L2))) <= 0;
}
bool segment_intersect(line L1, line L2){
  return segment_line_intersect(L1, L2) && segment_line_intersect(L2, L1);
}
point line_intersection(line L1, line L2){
  return L1.A + vec(L1) * cross(L2.A - L1.A, vec(L2)) / cross(vec(L1), vec(L2));
}
vector<double> unique_eps(vector<double> A){
  int N = A.size();
  sort(A.begin(), A.end());
  vector<double> A2;
  A2.push_back(A[0]);
  for (int i = 1; i < N; i++){
    if (A[i] - A[i - 1] > eps){
      A2.push_back(A[i]);
    }
  }
  return A2;
}
template <typename T>
struct slab_decomposition{
  function<T(T, T)> f;
  T e;
  vector<pair<line, T>> S;
  vector<double> X;
  int N;
  vector<vector<double>> Y;
  vector<int> P;
  vector<vector<tuple<int, int, T>>> E;
  slab_decomposition(function<T(T, T)> f, T e): f(f), e(e){
  }
  void add_segment(line s, T x){
    S.push_back(make_pair(s, x));
  }
  vector<vector<pair<T, int>>> build(){
    int M = S.size();
    for (int i = 0; i < M; i++){
      if (S[i].first.A.x > S[i].first.B.x){
        swap(S[i].first.A, S[i].first.B);
      }
    }
    for (int i = 0; i < M; i++){
      X.push_back(S[i].first.A.x);
      X.push_back(S[i].first.B.x);
    }
    for (int i = 0; i < M; i++){
      for (int j = i + 1; j < M; j++){
        if (!is_parallel(S[i].first, S[j].first) && segment_intersect(S[i].first, S[j].first)){
          X.push_back(line_intersection(S[i].first, S[j].first).x);
        }
      }
    }
    X = unique_eps(X);
    N = X.size();
    vector<int> L(M), R(M);
    for (int i = 0; i < M; i++){
      L[i] = lower_bound(X.begin(), X.end(), S[i].first.A.x - eps) - X.begin();
      R[i] = lower_bound(X.begin(), X.end(), S[i].first.B.x - eps) - X.begin();
    }
    vector<vector<double>> A(M, vector<double>(N));
    Y.resize(N);
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        A[i][j] = line_intersection(S[i].first, line(point(X[j], 0), point(X[j], 1))).y;
        Y[j].push_back(A[i][j]);
      }
    }
    for (int i = 0; i < N; i++){
      Y[i] = unique_eps(Y[i]);
    }
    vector<vector<int>> B(M, vector<int>(N));
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        B[i][j] = lower_bound(Y[j].begin(), Y[j].end(), A[i][j] - eps) - Y[j].begin();
      }
    }
    E.resize(N - 1);
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(-1, -1, e));
    }
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j < R[i]; j++){
        E[j].push_back(make_tuple(B[i][j], B[i][j + 1], S[i].second));
      }
    }
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(Y[i].size(), Y[i + 1].size(), e));
    }
    for (int i = 0; i < N - 1; i++){
      sort(E[i].begin(), E[i].end());
      if (!E[i].empty()){
        vector<tuple<int, int, T>> E2;
        int cnt = E[i].size();
        E2.push_back(E[i][0]);
        for (int j = 1; j < cnt; j++){
          if (get<0>(E[i][j - 1]) == get<0>(E[i][j]) && get<1>(E[i][j - 1]) == get<1>(E[i][j])){
            get<2>(E2.back()) = f(get<2>(E2.back()), get<2>(E[i][j]));
          } else {
            E2.push_back(E[i][j]);
          }
        }
        E[i] = E2;
      }
    }
    P.resize(N + 2);
    P[0] = 0;
    P[1] = 1;
    for (int i = 0; i < N - 1; i++){
      P[i + 2] = P[i + 1] + E[i].size() - 1;
    }
    P[N + 1] = P[N] + 1;
    vector<vector<int>> idL(N), idR(N);
    for (int i = 0; i < N; i++){
      idL[i] = vector<int>(Y[i].size() + 1);
      idR[i] = vector<int>(Y[i].size() + 1);
    }
    idL[0] = vector<int>(Y[0].size() + 1, 0);
    for (int i = 0; i < N - 1; i++){
      int cnt = E[i].size();
      for (int j = 0; j < cnt - 1; j++){
        for (int k = get<0>(E[i][j]) + 1; k <= get<0>(E[i][j + 1]); k++){
          idR[i][k] = P[i + 1] + j;
        }
        for (int k = get<1>(E[i][j]) + 1; k <= get<1>(E[i][j + 1]); k++){
          idL[i + 1][k] = P[i + 1] + j;
        }
      }
    }
    idR[N - 1] = vector<int>(Y[N - 1].size() + 1, P[N]);
    int V = P[N + 1];
    vector<vector<pair<T, int>>> G(V);
    for (int i = 0; i <= N; i++){
      for (int j = P[i]; j < P[i + 1] - 1; j++){
        G[j].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j + 1));
        G[j + 1].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j));
      }
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j <= Y[i].size(); j++){
        G[idL[i][j]].push_back(make_pair(e, idR[i][j]));
        G[idR[i][j]].push_back(make_pair(e, idL[i][j]));
      }
    }
    return G;
  }
  int find(point p){
    int x = lower_bound(X.begin(), X.end(), p.x - eps) - X.begin();
    if (x == 0){
      return 0;
    } else if (x == N){
      return P[N];
    } else {
      int ans = P[x];
      for (int i = 1; i < E[x - 1].size() - 1; i++){
        point A(X[x - 1], Y[x - 1][get<0>(E[x - 1][i])]);
        point B(X[x], Y[x][get<1>(E[x - 1][i])]);
        if (cross(B - A, p - A) > 0){
          ans++;
        }
      }
      return ans;
    }
  }
  vector<double> area(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 2; j++){
        double l = Y[i][get<0>(E[i][j + 1])] - Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j + 1])] - Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j] = (l + r) * (X[i + 1] - X[i]) / 2;
      }
    }
    return ans;
  }
  vector<double> length(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 1; j++){
        double l = Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j - 1] = hypot(X[i + 1] - X[i], r - l);
      }
    }
    return ans;
  }
};
int main(){
  cout << fixed << setprecision(20);
  while (true){
    int N, R;
    cin >> N >> R;
    if (N == 0 && R == 0){
      break;
    }
    vector<point> P(N + 1);
    for (int i = 0; i < N; i++){
      cin >> P[i].x >> P[i].y;
    }
    P[N] = P[0];
    vector<vector<point>> P2(N, vector<point>(6));
    for (int i = 0; i < N; i++){
      point A = P[i], B = P[i + 1];
      if (A.x + A.y > B.x + B.y){
        swap(A, B);
      }
      if (A.x - A.y > B.x - B.y){
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(B.x - R, B.y);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(A.x + R, A.y);
        P2[i][5] = point(A.x, A.y - R);
      } else {
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(A.x, A.y + R);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(B.x, B.y - R);
        P2[i][5] = point(A.x, A.y - R);
      }
    }
    for (int i = 0; i <= N; i++){
      P[i] = rotate(P[i], 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        P2[i][j] = rotate(P2[i][j], 1);
      }
    }
    slab_decomposition<__int128_t> D(bit_xor<__int128_t>(), 0);
    for (int i = 0; i < N; i++){
      D.add_segment(line(P[i], P[i + 1]), 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        D.add_segment(line(P2[i][j], P2[i][(j + 1) % 6]), (__int128_t) 1 << (i + 1));
      }
    }
    vector<vector<pair<__int128_t, int>>> E = D.build();
    int V = E.size();
    vector<__int128_t> A(V, -1);
    A[0] = 0;
    queue<int> Q;
    Q.push(0);
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      for (pair<__int128_t, int> e : E[v]){
        int w = e.second;
        if (A[w] == -1){
          A[w] = A[v] ^ e.first;
          Q.push(w);
        }
      }
    }
    vector<double> L = D.length();
    double ans = 0;
    for (int i = 0; i < V - 1; i++){
      if (A[i] != 1 && A[i + 1] == 1 || A[i] == 1 && A[i + 1] != 1){
        ans += L[i];
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 180
memory_kb: 39244
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
int sign(double x){
  if (x > eps){
    return 1;
  } else if (x < -eps){
    return -1;
  } else {
    return 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 abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
point rotate(point P, double t){
  return point(P.x * cos(t) - P.y * sin(t), P.x * sin(t) + P.y * cos(t));
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(){
  }
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool is_parallel(line L1, line L2){
  return abs(cross(vec(L1), vec(L2))) < eps;
}
bool segment_line_intersect(line L1, line L2){
  return sign(cross(L1.A - L2.A, vec(L2))) * sign(cross(L1.B - L2.A, vec(L2))) <= 0;
}
bool segment_intersect(line L1, line L2){
  return segment_line_intersect(L1, L2) && segment_line_intersect(L2, L1);
}
point line_intersection(line L1, line L2){
  return L1.A + vec(L1) * cross(L2.A - L1.A, vec(L2)) / cross(vec(L1), vec(L2));
}
vector<double> unique_eps(vector<double> A){
  int N = A.size();
  sort(A.begin(), A.end());
  vector<double> A2;
  A2.push_back(A[0]);
  for (int i = 1; i < N; i++){
    if (A[i] - A[i - 1] > eps){
      A2.push_back(A[i]);
    }
  }
  return A2;
}
template <typename T>
struct slab_decomposition{
  function<T(T, T)> f;
  T e;
  vector<pair<line, T>> S;
  vector<double> X;
  int N;
  vector<vector<double>> Y;
  vector<int> P;
  vector<vector<tuple<int, int, T>>> E;
  slab_decomposition(function<T(T, T)> f, T e): f(f), e(e){
  }
  void add_segment(line s, T x){
    S.push_back(make_pair(s, x));
  }
  vector<vector<pair<T, int>>> build(){
    int M = S.size();
    for (int i = 0; i < M; i++){
      if (S[i].first.A.x > S[i].first.B.x){
        swap(S[i].first.A, S[i].first.B);
      }
    }
    for (int i = 0; i < M; i++){
      X.push_back(S[i].first.A.x);
      X.push_back(S[i].first.B.x);
    }
    for (int i = 0; i < M; i++){
      for (int j = i + 1; j < M; j++){
        if (!is_parallel(S[i].first, S[j].first) && segment_intersect(S[i].first, S[j].first)){
          X.push_back(line_intersection(S[i].first, S[j].first).x);
        }
      }
    }
    X = unique_eps(X);
    N = X.size();
    vector<int> L(M), R(M);
    for (int i = 0; i < M; i++){
      L[i] = lower_bound(X.begin(), X.end(), S[i].first.A.x - eps) - X.begin();
      R[i] = lower_bound(X.begin(), X.end(), S[i].first.B.x - eps) - X.begin();
    }
    vector<vector<double>> A(M, vector<double>(N));
    Y.resize(N);
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        A[i][j] = line_intersection(S[i].first, line(point(X[j], 0), point(X[j], 1))).y;
        Y[j].push_back(A[i][j]);
      }
    }
    for (int i = 0; i < N; i++){
      Y[i] = unique_eps(Y[i]);
    }
    vector<vector<int>> B(M, vector<int>(N));
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        B[i][j] = lower_bound(Y[j].begin(), Y[j].end(), A[i][j] - eps) - Y[j].begin();
      }
    }
    E.resize(N - 1);
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(-1, -1, e));
    }
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j < R[i]; j++){
        E[j].push_back(make_tuple(B[i][j], B[i][j + 1], S[i].second));
      }
    }
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(Y[i].size(), Y[i + 1].size(), e));
    }
    for (int i = 0; i < N - 1; i++){
      sort(E[i].begin(), E[i].end());
    }
    P.resize(N + 2);
    P[0] = 0;
    P[1] = 1;
    for (int i = 0; i < N - 1; i++){
      P[i + 2] = P[i + 1] + E[i].size() - 1;
    }
    P[N + 1] = P[N] + 1;
    vector<vector<int>> idL(N), idR(N);
    for (int i = 0; i < N; i++){
      idL[i] = vector<int>(Y[i].size() + 1);
      idR[i] = vector<int>(Y[i].size() + 1);
    }
    idL[0] = vector<int>(Y[0].size() + 1, 0);
    for (int i = 0; i < N - 1; i++){
      int cnt = E[i].size();
      for (int j = 0; j < cnt - 1; j++){
        for (int k = get<0>(E[i][j]) + 1; k <= get<0>(E[i][j + 1]); k++){
          idR[i][k] = P[i + 1] + j;
        }
        for (int k = get<1>(E[i][j]) + 1; k <= get<1>(E[i][j + 1]); k++){
          idL[i + 1][k] = P[i + 1] + j;
        }
      }
    }
    idR[N - 1] = vector<int>(Y[N - 1].size() + 1, P[N]);
    int V = P[N + 1];
    vector<vector<pair<T, int>>> G(V);
    for (int i = 0; i <= N; i++){
      for (int j = P[i]; j < P[i + 1] - 1; j++){
        G[j].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j + 1));
        G[j + 1].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j));
      }
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j <= Y[i].size(); j++){
        G[idL[i][j]].push_back(make_pair(e, idR[i][j]));
        G[idR[i][j]].push_back(make_pair(e, idL[i][j]));
      }
    }
    return G;
  }
  vector<double> area(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 2; j++){
        double l = Y[i][get<0>(E[i][j + 1])] - Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j + 1])] - Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j] = (l + r) * (X[i + 1] - X[i]) / 2;
      }
    }
    return ans;
  }
  vector<double> length(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 1; j++){
        double l = Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j - 1] = hypot(X[i + 1] - X[i], r - l);
      }
    }
    return ans;
  }
};
int main(){
  cout << fixed << setprecision(20);
  while (true){
    int N, R;
    cin >> N >> R;
    if (N == 0 && R == 0){
      break;
    }
    vector<point> P(N + 1);
    for (int i = 0; i < N; i++){
      cin >> P[i].x >> P[i].y;
    }
    P[N] = P[0];
    vector<vector<point>> P2(N, vector<point>(6));
    for (int i = 0; i < N; i++){
      point A = P[i], B = P[i + 1];
      if (A.x + A.y > B.x + B.y){
        swap(A, B);
      }
      if (A.x - A.y > B.x - B.y){
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(B.x - R, B.y);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(A.x + R, A.y);
        P2[i][5] = point(A.x, A.y - R);
      } else {
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(A.x, A.y + R);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(B.x, B.y - R);
        P2[i][5] = point(A.x, A.y - R);
      }
    }
    for (int i = 0; i <= N; i++){
      P[i] = rotate(P[i], 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        P2[i][j] = rotate(P2[i][j], 1);
      }
    }
    slab_decomposition<__int128_t> D(bit_xor<__int128_t>(), 0);
    for (int i = 0; i < N; i++){
      D.add_segment(line(P[i], P[i + 1]), 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        D.add_segment(line(P2[i][j], P2[i][(j + 1) % 6]), (__int128_t) 1 << (i + 1));
      }
    }
    vector<vector<pair<__int128_t, int>>> E = D.build();
    int V = E.size();
    vector<__int128_t> A(V, -1);
    A[0] = 0;
    queue<int> Q;
    Q.push(0);
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      for (pair<__int128_t, int> e : E[v]){
        int w = e.second;
        if (A[w] == -1){
          A[w] = A[v] ^ e.first;
          Q.push(w);
        }
      }
    }
    vector<double> L = D.length();
    double ans = 0;
    for (int i = 0; i < V - 1; i++){
      if (A[i] != 1 && A[i + 1] == 1 || A[i] == 1 && A[i + 1] != 1){
        ans += L[i];
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 180
memory_kb: 39904
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
int sign(double x){
  if (x > eps){
    return 1;
  } else if (x < -eps){
    return -1;
  } else {
    return 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 abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
point rotate(point P, double t){
  return point(P.x * cos(t) - P.y * sin(t), P.x * sin(t) + P.y * cos(t));
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(){
  }
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool is_parallel(line L1, line L2){
  return abs(cross(vec(L1), vec(L2))) < eps;
}
bool segment_line_intersect(line L1, line L2){
  return sign(cross(L1.A - L2.A, vec(L2))) * sign(cross(L1.B - L2.A, vec(L2))) <= 0;
}
bool segment_intersect(line L1, line L2){
  return segment_line_intersect(L1, L2) && segment_line_intersect(L2, L1);
}
point line_intersection(line L1, line L2){
  return L1.A + vec(L1) * cross(L2.A - L1.A, vec(L2)) / cross(vec(L1), vec(L2));
}
vector<double> unique_eps(vector<double> A){
  int N = A.size();
  sort(A.begin(), A.end());
  vector<double> A2;
  A2.push_back(A[0]);
  for (int i = 1; i < N; i++){
    if (A[i] - A[i - 1] > eps){
      A2.push_back(A[i]);
    }
  }
  return A2;
}
template <typename T>
struct slab_decomposition{
  function<T(T, T)> f;
  T e;
  vector<pair<line, T>> S;
  vector<double> X;
  int N;
  vector<vector<double>> Y;
  vector<int> P;
  vector<vector<tuple<int, int, T>>> E;
  slab_decomposition(function<T(T, T)> f, T e): f(f), e(e){
  }
  void add_segment(line s, T x){
    S.push_back(make_pair(s, x));
  }
  vector<vector<pair<T, int>>> build(){
    int M = S.size();
    for (int i = 0; i < M; i++){
      if (S[i].first.A.x > S[i].first.B.x){
        swap(S[i].first.A, S[i].first.B);
      }
    }
    for (int i = 0; i < M; i++){
      X.push_back(S[i].first.A.x);
      X.push_back(S[i].first.B.x);
    }
    for (int i = 0; i < M; i++){
      for (int j = i + 1; j < M; j++){
        if (!is_parallel(S[i].first, S[j].first) && segment_intersect(S[i].first, S[j].first)){
          X.push_back(line_intersection(S[i].first, S[j].first).x);
        }
      }
    }
    X = unique_eps(X);
    N = X.size();
    vector<int> L(M), R(M);
    for (int i = 0; i < M; i++){
      L[i] = lower_bound(X.begin(), X.end(), S[i].first.A.x - eps) - X.begin();
      R[i] = lower_bound(X.begin(), X.end(), S[i].first.B.x - eps) - X.begin();
    }
    vector<vector<double>> A(M, vector<double>(N));
    Y.resize(N);
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        A[i][j] = line_intersection(S[i].first, line(point(X[j], 0), point(X[j], 1))).y;
        Y[j].push_back(A[i][j]);
      }
    }
    for (int i = 0; i < N; i++){
      Y[i] = unique_eps(Y[i]);
    }
    vector<vector<int>> B(M, vector<int>(N));
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        B[i][j] = lower_bound(Y[j].begin(), Y[j].end(), A[i][j] - eps) - Y[j].begin();
      }
    }
    E.resize(N - 1);
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(-1, -1, e));
    }
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j < R[i]; j++){
        E[j].push_back(make_tuple(B[i][j], B[i][j + 1], S[i].second));
      }
    }
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(Y[i].size(), Y[i + 1].size(), e));
    }
    for (int i = 0; i < N - 1; i++){
      sort(E[i].begin(), E[i].end());
      vector<tuple<int, int, T>> E2;
      int cnt = E[i].size();
      E2.push_back(E[i][0]);
      for (int j = 1; j < cnt; j++){
        if (get<0>(E[i][j - 1]) == get<0>(E[i][j]) && get<1>(E[i][j - 1]) == get<1>(E[i][j])){
          get<2>(E2.back()) = f(get<2>(E2.back()), get<2>(E[i][j]));
        } else {
          E2.push_back(E[i][j]);
        }
      }
    }
    P.resize(N + 2);
    P[0] = 0;
    P[1] = 1;
    for (int i = 0; i < N - 1; i++){
      P[i + 2] = P[i + 1] + E[i].size() - 1;
    }
    P[N + 1] = P[N] + 1;
    vector<vector<int>> idL(N), idR(N);
    for (int i = 0; i < N; i++){
      idL[i] = vector<int>(Y[i].size() + 1);
      idR[i] = vector<int>(Y[i].size() + 1);
    }
    idL[0] = vector<int>(Y[0].size() + 1, 0);
    for (int i = 0; i < N - 1; i++){
      int cnt = E[i].size();
      for (int j = 0; j < cnt - 1; j++){
        for (int k = get<0>(E[i][j]) + 1; k <= get<0>(E[i][j + 1]); k++){
          idR[i][k] = P[i + 1] + j;
        }
        for (int k = get<1>(E[i][j]) + 1; k <= get<1>(E[i][j + 1]); k++){
          idL[i + 1][k] = P[i + 1] + j;
        }
      }
    }
    idR[N - 1] = vector<int>(Y[N - 1].size() + 1, P[N]);
    int V = P[N + 1];
    vector<vector<pair<T, int>>> G(V);
    for (int i = 0; i <= N; i++){
      for (int j = P[i]; j < P[i + 1] - 1; j++){
        G[j].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j + 1));
        G[j + 1].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j));
      }
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j <= Y[i].size(); j++){
        G[idL[i][j]].push_back(make_pair(e, idR[i][j]));
        G[idR[i][j]].push_back(make_pair(e, idL[i][j]));
      }
    }
    return G;
  }
  vector<double> area(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 2; j++){
        double l = Y[i][get<0>(E[i][j + 1])] - Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j + 1])] - Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j] = (l + r) * (X[i + 1] - X[i]) / 2;
      }
    }
    return ans;
  }
  vector<double> length(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 1; j++){
        double l = Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j - 1] = hypot(X[i + 1] - X[i], r - l);
      }
    }
    return ans;
  }
};
int main(){
  cout << fixed << setprecision(20);
  while (true){
    int N, R;
    cin >> N >> R;
    if (N == 0 && R == 0){
      break;
    }
    vector<point> P(N + 1);
    for (int i = 0; i < N; i++){
      cin >> P[i].x >> P[i].y;
    }
    P[N] = P[0];
    vector<vector<point>> P2(N, vector<point>(6));
    for (int i = 0; i < N; i++){
      point A = P[i], B = P[i + 1];
      if (A.x + A.y > B.x + B.y){
        swap(A, B);
      }
      if (A.x - A.y > B.x - B.y){
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(B.x - R, B.y);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(A.x + R, A.y);
        P2[i][5] = point(A.x, A.y - R);
      } else {
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(A.x, A.y + R);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(B.x, B.y - R);
        P2[i][5] = point(A.x, A.y - R);
      }
    }
    for (int i = 0; i <= N; i++){
      P[i] = rotate(P[i], 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        P2[i][j] = rotate(P2[i][j], 1);
      }
    }
    slab_decomposition<__int128_t> D(bit_xor<__int128_t>(), 0);
    for (int i = 0; i < N; i++){
      D.add_segment(line(P[i], P[i + 1]), 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        D.add_segment(line(P2[i][j], P2[i][(j + 1) % 6]), (__int128_t) 1 << (i + 1));
      }
    }
    vector<vector<pair<__int128_t, int>>> E = D.build();
    int V = E.size();
    vector<__int128_t> A(V, -1);
    A[0] = 0;
    queue<int> Q;
    Q.push(0);
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      for (pair<__int128_t, int> e : E[v]){
        int w = e.second;
        if (A[w] == -1){
          A[w] = A[v] ^ e.first;
          Q.push(w);
        }
      }
    }
    vector<double> L = D.length();
    double ans = 0;
    for (int i = 0; i < V - 1; i++){
      if (A[i] != 1 && A[i + 1] == 1 || A[i] == 1 && A[i + 1] != 1){
        ans += L[i];
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 190
memory_kb: 40008
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
int sign(double x){
  if (x > eps){
    return 1;
  } else if (x < -eps){
    return -1;
  } else {
    return 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 abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
point rotate(point P, double t){
  return point(P.x * cos(t) - P.y * sin(t), P.x * sin(t) + P.y * cos(t));
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(){
  }
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool is_parallel(line L1, line L2){
  return abs(cross(vec(L1), vec(L2))) < eps;
}
bool segment_line_intersect(line L1, line L2){
  return sign(cross(L1.A - L2.A, vec(L2))) * sign(cross(L1.B - L2.A, vec(L2))) <= 0;
}
bool segment_intersect(line L1, line L2){
  return segment_line_intersect(L1, L2) && segment_line_intersect(L2, L1);
}
point line_intersection(line L1, line L2){
  return L1.A + vec(L1) * cross(L2.A - L1.A, vec(L2)) / cross(vec(L1), vec(L2));
}
vector<double> unique_eps(vector<double> A){
  int N = A.size();
  sort(A.begin(), A.end());
  vector<double> A2;
  A2.push_back(A[0]);
  for (int i = 1; i < N; i++){
    if (A[i] - A[i - 1] > eps){
      A2.push_back(A[i]);
    }
  }
  return A2;
}
template <typename T>
struct slab_decomposition{
  T e;
  vector<pair<line, T>> S;
  vector<double> X;
  int N;
  vector<vector<double>> Y;
  vector<int> P;
  vector<vector<tuple<int, int, T>>> E;
  slab_decomposition(T e): e(e){
  }
  void add_segment(line s, T x){
    S.push_back(make_pair(s, x));
  }
  vector<vector<pair<T, int>>> build(){
    int M = S.size();
    for (int i = 0; i < M; i++){
      if (S[i].first.A.x > S[i].first.B.x){
        swap(S[i].first.A, S[i].first.B);
      }
    }
    for (int i = 0; i < M; i++){
      X.push_back(S[i].first.A.x);
      X.push_back(S[i].first.B.x);
    }
    for (int i = 0; i < M; i++){
      for (int j = i + 1; j < M; j++){
        if (!is_parallel(S[i].first, S[j].first) && segment_intersect(S[i].first, S[j].first)){
          X.push_back(line_intersection(S[i].first, S[j].first).x);
        }
      }
    }
    X = unique_eps(X);
    N = X.size();
    vector<int> L(M), R(M);
    for (int i = 0; i < M; i++){
      L[i] = lower_bound(X.begin(), X.end(), S[i].first.A.x - eps) - X.begin();
      R[i] = lower_bound(X.begin(), X.end(), S[i].first.B.x - eps) - X.begin();
    }
    vector<vector<double>> A(M, vector<double>(N));
    Y.resize(N);
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        A[i][j] = line_intersection(S[i].first, line(point(X[j], 0), point(X[j], 1))).y;
        Y[j].push_back(A[i][j]);
      }
    }
    for (int i = 0; i < N; i++){
      Y[i] = unique_eps(Y[i]);
    }
    vector<vector<int>> B(M, vector<int>(N));
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j <= R[i]; j++){
        B[i][j] = lower_bound(Y[j].begin(), Y[j].end(), A[i][j] - eps) - Y[j].begin();
      }
    }
    E.resize(N - 1);
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(-1, -1, e));
    }
    for (int i = 0; i < M; i++){
      for (int j = L[i]; j < R[i]; j++){
        E[j].push_back(make_tuple(B[i][j], B[i][j + 1], S[i].second));
      }
    }
    for (int i = 0; i < N - 1; i++){
      E[i].push_back(make_tuple(Y[i].size(), Y[i + 1].size(), e));
    }
    for (int i = 0; i < N - 1; i++){
      sort(E[i].begin(), E[i].end());
      vector<tuple<int, int, T>> E2;
      int cnt = E[i].size();
      E2.push_back(E[i][0]);
      for (int j = 1; j < cnt; j++){
        if (get<0>(E[i][j - 1]) == get<0>(E[i][j]) && get<1>(E[i][j - 1]) == get<1>(E[i][j])){
          get<2>(E2.back()) ^= get<2>(E[i][j]);
        } else {
          E2.push_back(E[i][j]);
        }
      }
    }
    P.resize(N + 2);
    P[0] = 0;
    P[1] = 1;
    for (int i = 0; i < N - 1; i++){
      P[i + 2] = P[i + 1] + E[i].size() - 1;
    }
    P[N + 1] = P[N] + 1;
    vector<vector<int>> idL(N), idR(N);
    for (int i = 0; i < N; i++){
      idL[i] = vector<int>(Y[i].size() + 1);
      idR[i] = vector<int>(Y[i].size() + 1);
    }
    idL[0] = vector<int>(Y[0].size() + 1, 0);
    for (int i = 0; i < N - 1; i++){
      int cnt = E[i].size();
      for (int j = 0; j < cnt - 1; j++){
        for (int k = get<0>(E[i][j]) + 1; k <= get<0>(E[i][j + 1]); k++){
          idR[i][k] = P[i + 1] + j;
        }
        for (int k = get<1>(E[i][j]) + 1; k <= get<1>(E[i][j + 1]); k++){
          idL[i + 1][k] = P[i + 1] + j;
        }
      }
    }
    idR[N - 1] = vector<int>(Y[N - 1].size() + 1, P[N]);
    int V = P[N + 1];
    vector<vector<pair<T, int>>> G(V);
    for (int i = 0; i <= N; i++){
      for (int j = P[i]; j < P[i + 1] - 1; j++){
        G[j].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j + 1));
        G[j + 1].push_back(make_pair(get<2>(E[i - 1][j - P[i] + 1]), j));
      }
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j <= Y[i].size(); j++){
        G[idL[i][j]].push_back(make_pair(e, idR[i][j]));
        G[idR[i][j]].push_back(make_pair(e, idL[i][j]));
      }
    }
    return G;
  }
  vector<double> area(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 2; j++){
        double l = Y[i][get<0>(E[i][j + 1])] - Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j + 1])] - Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j] = (l + r) * (X[i + 1] - X[i]) / 2;
      }
    }
    return ans;
  }
  vector<double> length(){
    int V = P[N + 1];
    vector<double> ans(V, -1);
    for (int i = 0; i < N - 1; i++){
      for(int j = 1; j < E[i].size() - 1; j++){
        double l = Y[i][get<0>(E[i][j])];
        double r = Y[i + 1][get<1>(E[i][j])];
        ans[P[i + 1] + j - 1] = hypot(X[i + 1] - X[i], r - l);
      }
    }
    return ans;
  }
};
int main(){
  cout << fixed << setprecision(20);
  while (true){
    int N, R;
    cin >> N >> R;
    if (N == 0 && R == 0){
      break;
    }
    vector<point> P(N + 1);
    for (int i = 0; i < N; i++){
      cin >> P[i].x >> P[i].y;
    }
    P[N] = P[0];
    vector<vector<point>> P2(N, vector<point>(6));
    for (int i = 0; i < N; i++){
      point A = P[i], B = P[i + 1];
      if (A.x + A.y > B.x + B.y){
        swap(A, B);
      }
      if (A.x - A.y > B.x - B.y){
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(B.x - R, B.y);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(A.x + R, A.y);
        P2[i][5] = point(A.x, A.y - R);
      } else {
        P2[i][0] = point(A.x - R, A.y);
        P2[i][1] = point(A.x, A.y + R);
        P2[i][2] = point(B.x, B.y + R);
        P2[i][3] = point(B.x + R, B.y);
        P2[i][4] = point(B.x, B.y - R);
        P2[i][5] = point(A.x, A.y - R);
      }
    }
    for (int i = 0; i <= N; i++){
      P[i] = rotate(P[i], 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        P2[i][j] = rotate(P2[i][j], 1);
      }
    }
    slab_decomposition<__int128_t> D(0);
    for (int i = 0; i < N; i++){
      D.add_segment(line(P[i], P[i + 1]), 1);
    }
    for (int i = 0; i < N; i++){
      for (int j = 0; j < 6; j++){
        D.add_segment(line(P2[i][j], P2[i][(j + 1) % 6]), (__int128_t) 1 << (i + 1));
      }
    }
    vector<vector<pair<__int128_t, int>>> E = D.build();
    int V = E.size();
    vector<__int128_t> A(V, -1);
    A[0] = 0;
    queue<int> Q;
    Q.push(0);
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      for (pair<__int128_t, int> e : E[v]){
        int w = e.second;
        if (A[w] == -1){
          A[w] = A[v] ^ e.first;
          Q.push(w);
        }
      }
    }
    vector<double> L = D.length();
    double ans = 0;
    for (int i = 0; i < V - 1; i++){
      if (A[i] != 1 && A[i + 1] == 1 || A[i] == 1 && A[i + 1] != 1){
        ans += L[i];
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 190
memory_kb: 40048
final_rank: 20

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



#define SIZE 10005


enum TYPE{
	Top,
	Left,
	Under,
	Right,
};


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{
		double tmp = (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y);
		return sqrt(tmp) < EPS;
	}

	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}

	void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}
	Point p[2];
};


int N,num_point;
int num_shore,num_line;
map<pair<int,int>,bool> MAP;
double R;
double NUM = 1000000;
Point SUB[105][4],point[SIZE];
Line shore[105],line[SIZE];
vector<Point> line_P[SIZE];
Polygon P;


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));
}

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;
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0,Point p1,Point p2){

	Vector a = p1 - p0;
	Vector b = p2 - p0;

	if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
	if(cross(a,b) < -EPS)return CLOCKWISE;
	if(dot(a,b) < -EPS)return ONLINE_BACK;
	if(a.norm() < b.norm())return ONLINE_FRONT;

	return ON_SEGMENT;
}

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[1].y-A.p[0].y)/(A.p[1].x-A.p[0].x);
	}
}

//切片を求める関数
double calc_add(Line line){

	double slope = calc_slope(line);

	if(fabs(slope-DBL_MAX) < EPS){

		return DBL_MAX;

	}else if(fabs(slope) < EPS){

		return line.p[0].y;

	}else{

		return line.p[0].y-slope*line.p[0].x;
	}
}

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;
}


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 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);
}

//交点を求める関数
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(fabs(x1-x2) > EPS){
		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]);
}

/*
 * 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(abs(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);
}

double calc_manhattan_dist(Point p){

	double ret = BIG_NUM;

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

		for(int k = 0; k < 2; k++){

			ret = min(ret,fabs(p.x-shore[i].p[k].x)+fabs(p.y-shore[i].p[k].y));
		}

		Line horizon = Line(Point(-NUM,p.y),Point(NUM,p.y));
		if(is_Cross(horizon,shore[i])){

			Point tmp_p = calc_Cross_Point(horizon,shore[i]);

			ret = min(ret,fabs(tmp_p.x-p.x));
		}

		Line vertical = Line(Point(p.x,-NUM),Point(p.x,NUM));
		if(is_Cross(vertical,shore[i])){

			Point tmp_p = calc_Cross_Point(vertical,shore[i]);

			ret = min(ret,fabs(tmp_p.y-p.y));
		}
	}

	return ret;
}

int get_index(Point p){

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

		if(point[i] == p){

			return i;
		}
	}
	point[num_point] = p;
	int ret = num_point;
	num_point++;

	return ret;
}

void func(){

	num_point = 0;
	MAP.clear();
	P.clear();
	for(int i = 0; i < SIZE; i++){

		line_P[i].clear();
	}

	double x,y;

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

		scanf("%lf %lf",&x,&y);
		P.push_back(Point(x,y));

		SUB[i][Top] = Point(x,y+R);
		SUB[i][Left] = Point(x-R,y);
		SUB[i][Under] = Point(x,y-R);
		SUB[i][Right] = Point(x+R,y);

		for(int k = 0; k < 4; k++){

			line[num_line++] = Line(SUB[i][k],SUB[i][(k+1)%4]);
		}
	}

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

		shore[num_shore].p[0] = P[i];
		shore[num_shore++].p[1] = P[(i+1)%N];
	}

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

			line[num_line].p[0] = SUB[i][k];
			line[num_line].p[1] = SUB[(i+1)%N][k];
			num_line++;
		}
	}

	double ans = 0;

	//線分上にのっている点を列挙
	for(int i = 0; i < num_line; i++){

		line_P[i].push_back(line[i].p[0]);
		line_P[i].push_back(line[i].p[1]);

		for(int k = i+1; k < num_line; k++){
			if(is_Cross(line[i],line[k])){

				Point cross_p = calc_Cross_Point(line[i],line[k]);
				line_P[i].push_back(cross_p);
				line_P[k].push_back(cross_p);
			}
		}
		sort(line_P[i].begin(),line_P[i].end());
		line_P[i].erase(unique(line_P[i].begin(),line_P[i].end()),line_P[i].end());

		for(int k = 1; k < line_P[i].size(); k++){

			Point mid_p = (line_P[i][k-1]+line_P[i][k])/2;
			if(contains(P,mid_p) == 0)continue;

			double tmp_dist =  calc_manhattan_dist(mid_p);
			if(tmp_dist+EPS < R)continue;

			int a = get_index(line_P[i][k-1]);
			int b = get_index(line_P[i][k]);

			if(a > b)swap(a,b);

			auto at = MAP.find(make_pair(a,b));
			if(at != MAP.end())continue;

			MAP[make_pair(a,b)] = true;

			ans += calc_dist(line_P[i][k-1],line_P[i][k]);
		}
    }

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

int main(){

	while(true){

		scanf("%d %lf",&N,&R);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 4276
final_rank: 4

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



#define SIZE 10005


enum TYPE{
	Top,
	Left,
	Under,
	Right,
};


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{
		double tmp = (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y);
		return sqrt(tmp) < EPS;
	}

	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}

	void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}
	Point p[2];
};


int N,num_point;
int num_shore,num_line;
map<pair<int,int>,bool> MAP;
double R;
double NUM = 1000000;
Point SUB[105][4],point[SIZE];
Line shore[105],line[SIZE];
vector<Point> line_P[SIZE];
Polygon P;


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));
}

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;
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0,Point p1,Point p2){

	Vector a = p1 - p0;
	Vector b = p2 - p0;

	if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
	if(cross(a,b) < -EPS)return CLOCKWISE;
	if(dot(a,b) < -EPS)return ONLINE_BACK;
	if(a.norm() < b.norm())return ONLINE_FRONT;

	return ON_SEGMENT;
}

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[1].y-A.p[0].y)/(A.p[1].x-A.p[0].x);
	}
}

//切片を求める関数
double calc_add(Line line){

	double slope = calc_slope(line);

	if(fabs(slope-DBL_MAX) < EPS){

		return DBL_MAX;

	}else if(fabs(slope) < EPS){

		return line.p[0].y;

	}else{

		return line.p[0].y-slope*line.p[0].x;
	}
}

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;
}


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 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);
}

//交点を求める関数
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(fabs(x1-x2) > EPS){
		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]);
}

/*
 * 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(abs(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);
}

double calc_manhattan_dist(Point p){

	double ret = BIG_NUM;

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

		for(int k = 0; k < 2; k++){

			ret = min(ret,fabs(p.x-shore[i].p[k].x)+fabs(p.y-shore[i].p[k].y));
		}

		Line horizon = Line(Point(-NUM,p.y),Point(NUM,p.y));
		if(is_Cross(horizon,shore[i])){

			Point tmp_p = calc_Cross_Point(horizon,shore[i]);

			ret = min(ret,fabs(tmp_p.x-p.x));
		}

		Line vertical = Line(Point(p.x,-NUM),Point(p.x,NUM));
		if(is_Cross(vertical,shore[i])){

			Point tmp_p = calc_Cross_Point(vertical,shore[i]);

			ret = min(ret,fabs(tmp_p.y-p.y));
		}
	}

	return ret;
}

int get_index(Point p){

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

		if(point[i] == p){

			return i;
		}
	}
	point[num_point] = p;
	int ret = num_point;
	num_point++;

	return ret;
}

void func(){

	num_point = 0;
	MAP.clear();
	P.clear();
	for(int i = 0; i < SIZE; i++){

		line_P[i].clear();
	}

	double x,y;

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

		scanf("%lf %lf",&x,&y);
		P.push_back(Point(x,y));

		SUB[i][Top] = Point(x,y+R);
		SUB[i][Left] = Point(x-R,y);
		SUB[i][Under] = Point(x,y-R);
		SUB[i][Right] = Point(x+R,y);

		for(int k = 0; k < 4; k++){

			line[num_line++] = Line(SUB[i][k],SUB[i][(k+1)%4]);
		}
	}

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

		shore[num_shore].p[0] = P[i];
		shore[num_shore++].p[1] = P[(i+1)%N];

		line[num_line++] = shore[i];
	}

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

			line[num_line].p[0] = SUB[i][k];
			line[num_line].p[1] = SUB[(i+1)%N][k];
			num_line++;
		}
	}

	double ans = 0;

	//線分上にのっている点を列挙
	for(int i = 0; i < num_line; i++){

		line_P[i].push_back(line[i].p[0]);
		line_P[i].push_back(line[i].p[1]);

		for(int k = i+1; k < num_line; k++){
			if(is_Cross(line[i],line[k])){

				Point cross_p = calc_Cross_Point(line[i],line[k]);
				line_P[i].push_back(cross_p);
				line_P[k].push_back(cross_p);
			}
		}
		sort(line_P[i].begin(),line_P[i].end());
		line_P[i].erase(unique(line_P[i].begin(),line_P[i].end()),line_P[i].end());

		for(int k = 1; k < line_P[i].size(); k++){

			Point mid_p = (line_P[i][k-1]+line_P[i][k])/2;
			if(contains(P,mid_p) == 0)continue;

			double tmp_dist =  calc_manhattan_dist(mid_p);
			if(tmp_dist+EPS < R)continue;

			int a = get_index(line_P[i][k-1]);
			int b = get_index(line_P[i][k]);

			if(a > b)swap(a,b);

			auto at = MAP.find(make_pair(a,b));
			if(at != MAP.end())continue;

			MAP[make_pair(a,b)] = true;

			ans += calc_dist(line_P[i][k-1],line_P[i][k]);
		}
    }

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

int main(){

	while(true){

		scanf("%d %lf",&N,&R);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 4144
final_rank: 5

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

typedef long double ld;

struct po{
	ld x;
	ld y;
	po(ld a){ x=a; y=0; }
	po(ld a,ld b){ x=a; y=b; }
	po(){}
	inline ld operator()(const po& rhs) const {
		return x*rhs.x+y*rhs.y;
	}
	inline po& operator +=(const po& rhs){
		x += rhs.x;
		y += rhs.y;
		return *this;
	}
	inline po& operator -=(const po& rhs){
		x -= rhs.x;
		y -= rhs.y;
		return *this;
	}
	inline po& operator *=(const po& rhs){
		ld x_ = x*rhs.x-y*rhs.y;
		y = x*rhs.y+y*rhs.x;
		x = x_;
		return *this;
	}
	inline po& operator /=(const po& rhs){
		ld x_ = x*rhs.x+y*rhs.y;
		y = -x*rhs.y+y*rhs.x;
		x = x_;
		ld nor = rhs(rhs);
		x /= nor;
		y /= nor;
		return *this;
	}
	bool operator < ( const po& rhs )const {
		return false;
	}
};

inline po operator+(const po& a, const po& b){return po(a) += b;}
inline po operator-(const po& a, const po& b){return po(a) -= b;}
inline po operator*(const po& a, const po& b){return po(a) *= b;}
inline po operator/(const po& a, const po& b){return po(a) /= b;}
inline po similar(const po& a, const po& b, const po& c,const po &p, const po& q){
	return p+(q-p)*(c-a)/(b-a);
}

typedef pair<po,po> se;
#define fr first
#define sc second

struct li{
	ld a;
	ld b;
	ld c;
	li(po p,po q){
		a = q.y-p.y;
		b = p.x-q.x;
		c = p.y*q.x-p.x*q.y;
	}
	li(){}
	inline ld operator()(const po& p) const {
		return a*p.x+b*p.y+c;
	}
};

void intersect(const li &l, const li &m, po* &ret){
	if(abs(l.a*m.b-m.a*l.b) <= 1e-18){
		ret = nullptr;
		return;
	}
	ret = new po;
	ret->x = -(l.c*m.b-m.c*l.b)/(l.a*m.b-m.a*l.b);
	ret->y = -(l.a*m.c-m.a*l.c)/(l.a*m.b-m.a*l.b);
}
inline bool on(const po &p, const se &s){
	return (s.fr-p)(s.sc-p) <= 1e-9;
}
void intersect(const se &s, const li &l, po* &ret){
	li m = li(s.fr,s.sc);
	po *p;
	intersect(l,m,p);
	if(p == nullptr || on(*p,s))ret = p;
	else {
		delete p;
		ret = nullptr;
	}
}
void intersect(const se &s, const se & t, po* &ret){
	li l = li(s.fr,s.sc);
	li m = li(t.fr,t.sc);
	po *p;
	intersect(l,m,p);
	if(p == nullptr || (on(*p,s)&&on(*p,t)))ret = p;
	else {
		delete p;
		ret = nullptr;
	}
}
inline ld dist(const po &p, const po &q){
	return sqrt((p-q)(p-q));
}
inline li perpen(const po &p, const li &l){
	li ret;
	ret.a = l.b;
	ret.b = -l.a;
	ret.c = l.a*p.y-l.b*p.x;
	return ret;
}
inline po perpen_leg(const po &p, const li &l){
	po ret;
	li m = perpen(p,l);
	ret.x = -(l.c*m.b-m.c*l.b)/(l.a*m.b-m.a*l.b);
	ret.y = -(l.a*m.c-m.a*l.c)/(l.a*m.b-m.a*l.b);
	return ret;
}
inline ld dist(const po &p, const se &s){
	po h = perpen_leg(p,li(s.fr,s.sc));
	if(on(h,s))return dist(p,h);
	else return min( dist(p,s.fr) , dist(p,s.sc) );
}

int n,r;
po p[102];

inline ld dist_1(const po &p, const po &q){
	return abs(p.x-q.x)+abs(p.y-q.y);
}
inline ld dist_1(const po &p, const se &s){
	ld ret = min(dist_1(p,s.fr),dist_1(p,s.sc));
	po* q;
	intersect(s,li(p,p+1),q);
	if(q != nullptr){
		ret = min( ret , dist_1(p,*q) );
		delete q;
	}
	intersect(s,li(p,p+po(0,1)),q);
	if(q != nullptr){
		ret = min( ret , dist_1(p,*q) );
		delete q;
	}
	return ret;
}

bool inside(po q){
	cout.precision(20);
	//cout << q.x << " " << q.y << endl;
	
	int cnt = 0;
	for(int i = 0 ; i < n ; i ++){
		po* s;
		intersect(se(p[i],p[i+1]),se(q,q-1000000.0),s);
		if(s != nullptr){
			delete s;
			cnt ++;
		}
	}
	//cout << "cnt = " << cnt << endl;
	if(cnt%2 == 0)return false;
	//puts("A");
	for(int i = 0 ; i < n ; i ++){
		if(dist_1(q,se(p[i],p[i+1])) <= r)return false;
	}
	//cout << dist_1(q,se(p[0],p[1])) << endl;
	//puts("B");
	return true;
}

int main_solve(){
	cin >> n >> r;
	if(n == 0)return 1;
	for(int i = 0 ; i < n ; i ++){
		cin >> p[i].x >> p[i].y;
	}
	p[n] = p[0];
	
	vector<se> L;
	po d[4];
	d[0].x = r; d[0].y = 0;
	d[1].x = 0; d[1].y = r;
	d[2].x = -r; d[2].y = 0;
	d[3].x = 0; d[3].y = -r;
	for(int i = 0 ; i < n ; i ++){
		for(int j = 0 ; j < 4 ; j ++){
			L.push_back(se(p[i]+d[j],p[i]+d[(j+1)&3]));
		}
	}
	for(int i = 0 ; i < n ; i ++){
		for(int j = 0 ; j < 4 ; j ++){
			L.push_back(se(p[i]+d[j],p[i+1]+d[j]));
		}
	}
	
	
	/*cout << L.size() << endl;
	for(int i = 0 ; i < L.size() ; i ++){
		cout << "(" << L[i].fr.x << "," << L[i].fr.y << ")"
		<< " " << "(" << L[i].sc.x << "," << L[i].sc.y << ")" << endl;
	}*/
	
	vector<se> L_;
	for(int i = 0 ; i < L.size() ; i ++){
		for(int j = i+1 ; j <= L.size() ; j ++){
			if(j == L.size()){
				L_.push_back(L[i]);
				break;
			}
			li l = li(L[i].fr,L[i].sc);
			li m = li(L[j].fr,L[j].sc);
			/*if(i == 12 && j == 14){
				cout << "(" << L[i].fr.x << "," << L[i].fr.y << ")" << ",";
				cout << "(" << L[i].sc.x << "," << L[i].sc.y << ")" << endl;
				cout << "(" << L[j].fr.x << "," << L[j].fr.y << ")" << ",";
				cout << "(" << L[j].sc.x << "," << L[j].sc.y << ")" << endl;
				cout << l.a << " " << l.b << endl;
				cout << m.a << " " << m.b << endl;
			}*/
			if(abs(l.a*m.b-m.a*l.b) <= 1e-18){
				po X_ = similar(L[j].fr,L[j].sc,L[i].fr,po(0.0),po(1.0));
				po Y_ = similar(L[j].fr,L[j].sc,L[i].sc,po(0.0),po(1.0));
				if(abs(X_.y) > 1e-10 || abs(Y_.y) > 1e-10){
					continue;
				}
				ld X = X_.x;
				ld Y = Y_.x;
				if(max(X,Y) <= 1e-10)continue;
				if(min(X,Y) >= 1.0+1e-10)continue;
				po FR = similar(0.0,1.0,min(min(X,Y),(ld)0.0),L[j].fr,L[j].sc);
				po SC = similar(0.0,1.0,max(max(X,Y),(ld)1.0),L[j].fr,L[j].sc);
				L[j].fr = FR;
				L[j].sc = SC;
				break;
			}
		}
	}
	L = L_;
	
	/*cout << L.size() << endl;
	for(int i = 0 ; i < L.size() ; i ++){
		cout << i << ":";
		cout << "(" << L[i].fr.x << "," << L[i].fr.y << ")"
		<< " " << "(" << L[i].sc.x << "," << L[i].sc.y << ")" << endl;
	}*/
	
	ld ret = 0.0;
	for(int xxx = 0 ; xxx < L.size() ; xxx ++){
		se l = L[xxx];
		vector<pair<ld,po>> vec;
		vec.push_back(pair<ld,po>(0.0,l.fr));
		vec.push_back(pair<ld,po>(1.0,l.sc));
		for(int yyy = 0 ; yyy < L.size() ; yyy ++){
			if(xxx == yyy)continue;
			se m = L[yyy];
			po* p;
			intersect(l,m,p);
			if(p == nullptr)continue;
			else {
				vec.push_back(pair<ld,po>(similar(l.fr,l.sc,*p,0.0,1.0).x,*p));
				delete p;
			}
		}
		sort(vec.begin(),vec.end());
		
		/*if(xxx == 20){
			for(int i = 0 ; i < vec.size() ; i ++){
				cout << vec[i].fr << ":"
				<< "(" << vec[i].sc.x << "," << vec[i].sc.y << ")" << endl;
			}
		}*/
		po D = po(l.fr.y-l.sc.y,l.sc.x-l.fr.x);
		D /= sqrt(D(D));
		D *= 1e-6;
		ld dx = D.x;
		ld dy = D.y;
		//ld dx = (l.fr.y-l.sc.y)*1e-12;
		//ld dy = (l.sc.x-l.fr.x)*1e-12;
		for(int i = 0 ; i+1 < vec.size() ; i ++){
			bool b1 = inside((vec[i].sc+vec[i+1].sc)/2.0+po(dx,dy));
			bool b2 = inside((vec[i].sc+vec[i+1].sc)/2.0-po(dx,dy));
			if(b1 != b2){
				ret += dist(vec[i].sc,vec[i+1].sc);
			}
		}
		//if(xxx == 20)break;
	}
	cout.precision(20);
	cout << ret << endl;
	return 0;
}

int main(){
	while(!main_solve()){};
}
accuracy: 1
time_ms: 2390
memory_kb: 3376
final_rank: 12

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;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

//幾何構造
/*
  xy平面上の点は複素数型、
  線分及び直線は要素数2の配列に端点を記憶する
*/
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(){}
};
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
}

//平行判定
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]);
}

//交差判定
bool intersectLS(const L& l, const L& s){
    return cross(l[1]-l[0], s[0]-l[0])*
        cross(l[1]-l[0], s[1]-l[0]) < 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 );
}
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;
}
//直線の交点
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]);
}

//多角形の包含判定(1:内側, 0:辺上, -1:外側)
int inPoly(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 = 1-ret;
    }
    return ret;
}

//L1ノルム(マンハッタン距離)
double L1distance(const P &a, const P &b){
    return abs(b.X -a.X) +abs(b.Y -a.Y);
}
double L1distanceSP(const L &s, const P &p){
    double ret = INF;
    for(int i=0; i<2; i++){
        L gl(p, p +P(i, 1-i));
        if(!isParallel(s, gl) && intersectLS(gl, s)){
            P cp = crosspointLL(s, L(p, p+P(i,1-i)));
            ret = min(ret, abs(p -cp));
        }
        ret = min(ret, L1distance(p, s[i]));
    }
    return ret;
}

//線分アレンジメント
/*
  線分を重複・交差が無いように分解する
  例えばバツ印は4本の線分になる
*/
vector<L> arrangement(const vector<L> &e){
    vector<VP> cp(e.size());
    for(int i=0; i<(int)e.size(); i++){
        for(int j=i+1; j<(int)e.size(); j++){
            if(!isParallel(e[i], e[j]) && intersectSS(e[i], e[j])){
                P cpij = crosspointLL(e[i], e[j]);
                cp[i].push_back(cpij);
                cp[j].push_back(cpij);
            }
        }
        sort(cp[i].begin(), cp[i].end());
        cp[i].erase(unique(cp[i].begin(), cp[i].end()), cp[i].end());
    }
 
    vector<L> ret;
    for(int i=0; i<(int)e.size(); i++){
        for(int j=0; j<(int)cp[i].size()-1; j++){
            ret.push_back(L(cp[i][j], cp[i][j+1]));
        }
    }
    sort(ret.begin(), ret.end());
    ret.erase(unique(ret.begin(), ret.end()), ret.end());
    return ret;
}


int main(){
    while(true){
        int n,r;
        cin >> n >> r;
        if(n == 0) break;

        //入力受け取り
        VP v(n); //多角形の頂点
        for(int i=0; i<n; i++){
            double x,y;
            cin >> x >> y;
            v[i] = P(x, y);
        }
        
        //各頂点について、上下左右に距離rの点をとって正方形をつくる
        vector<VP> sq(n, VP(4));
        for(int i=0; i<n; i++){
            sq[i][0] = v[i] +P(r, 0);
            sq[i][1] = v[i] +P(0, r);
            sq[i][2] = v[i] +P(-r, 0);
            sq[i][3] = v[i] +P(0, -r);
        }

        /*
          線分リストに、
          (1)もともとの多角形の辺
          (2)各頂点について考えた正方形の辺
          (3)隣り合う頂点の正方形の、対応する頂点を結んだ線分
          を入れる
        */
        vector<L> segs; //線分リスト
        for(int i=0; i<n; i++){
            segs.push_back(L(v[i], v[(i+1)%n]));
            for(int j=0; j<4; j++){
                segs.push_back(L(sq[i][j], sq[(i+1)%n][j]));
                segs.push_back(L(sq[i][j], sq[i][(j+1)%4]));
            }
        }
        //侵食後の海岸線の候補となる線分
        vector<L> cand = arrangement(segs);

        /*
          候補となる線分のうち、最終的に残るのは、
          (1)もともとの多角形よりも内側にあり、
          (2)各辺からマンハッタン距離がr以上
          の点であるので、それらの長さを足し合わせる
         */
        double ans = 0;
        for(int i=0; i<(int)cand.size(); i++){
            bool removed = false;
            for(int j=0; j<n; j++){
                P mid = (cand[i][0] +cand[i][1])/2.0;
                if(L1distanceSP(L(v[j], v[(j+1)%n]), mid) +EPS < r || inPoly(mid, v) == -1){
                    removed = true;
                    break;
                }
            }
            if(!removed){
                ans += abs(cand[i][1] -cand[i][0]);
            }
        }

        //小数点以下10桁で解を出力
        cout << fixed;
        cout << setprecision(10);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1310
memory_kb: 3928
final_rank: 11

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;
#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(){}
};

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
}

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]);
}

bool intersectLS(const L& l, const L& s){
    return cross(l[1]-l[0], s[0]-l[0])*
        cross(l[1]-l[0], s[1]-l[0]) < 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 );
}
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;
}
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]);
}

double L1distance(const P &a, const P &b){
    return abs(b.X -a.X) +abs(b.Y -a.Y);
}
double L1distanceSP(const L &s, const P &p){
    double ret = INF;
    for(int i=0; i<2; i++){
        L gl(p, p +P(i, 1-i));
        if(!isParallel(s, gl) && intersectLS(gl, s)){
            P cp = crosspointLL(s, L(p, p+P(i,1-i)));
            ret = min(ret, abs(p -cp));
        }
        ret = min(ret, L1distance(p, s[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 = 1-ret;
    }
    return ret;
}
vector<L> arrangement(const vector<L> &e){
    vector<VP> cp(e.size());
    for(int i=0; i<(int)e.size(); i++){
        for(int j=i+1; j<(int)e.size(); j++){
            if(!isParallel(e[i], e[j]) && intersectSS(e[i], e[j])){
                P cpij = crosspointLL(e[i], e[j]);
                cp[i].push_back(cpij);
                cp[j].push_back(cpij);
            }
        }
        sort(cp[i].begin(), cp[i].end());
        cp[i].erase(unique(cp[i].begin(), cp[i].end()), cp[i].end());
    }

    vector<L> ret;
    for(int i=0; i<(int)e.size(); i++){
        for(int j=0; j<(int)cp[i].size()-1; j++){
            ret.push_back(L(cp[i][j], cp[i][j+1]));
        }
    }
    sort(ret.begin(), ret.end());
    ret.erase(unique(ret.begin(), ret.end()), ret.end());
    return ret;
}


int main(){
    while(1){
        int n,r;
        cin >> n >> r;
        if(n==0) break;
        
        VP v(n);
        for(int i=0; i<n; i++){
            double x,y;
            cin >> x >> y;
            v[i] = P(x,y);
        }
        vector<VP> sq(n, VP(4));
        for(int i=0; i<n; i++){
            sq[i][0] = v[i] +P(r, 0);
            sq[i][1] = v[i] +P(0, r);
            sq[i][2] = v[i] +P(-r, 0);
            sq[i][3] = v[i] +P(0, -r);
        }

        vector<L> l;
        l.reserve(9*n);
        for(int i=0; i<n; i++){
            l.push_back(L(v[i], v[(i+1)%n]));
            for(int j=0; j<4; j++){
                l.push_back(L(sq[i][j], sq[(i+1)%n][j]));
                l.push_back(L(sq[i][j], sq[i][(j+1)%4]));
            }
        }
        vector<L> cand = arrangement(l);

        double ans = 0;
        for(int i=0; i<(int)cand.size(); i++){
            bool rem = true;
            for(int j=0; j<n; j++){
                P mid = (cand[i][0] +cand[i][1])/2.0;
                if(L1distanceSP(L(v[j], v[(j+1)%n]), mid) +EPS < r || in_poly(mid, v) == -1){
                    rem = false;
                    break;
                }
            }
            if(rem){
                ans += abs(cand[i][1] -cand[i][0]);
            }
        }
        cout << fixed;
        cout << setprecision(10);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1320
memory_kb: 3836
final_rank: 10

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;
#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(){}
};

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);
}

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]);
}

bool intersectLS(const L& l, const L& s){
    return cross(l[1]-l[0], s[0]-l[0])*
        cross(l[1]-l[0], s[1]-l[0]) < 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 );
}
bool intersectSP(const L& s, const P& p){
    return abs(s[0]-p) +abs(s[1]-p) -abs(s[1]-s[0]) < EPS;
}
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]);
}

double L1distance(const P &a, const P &b){
    return abs(b.X -a.X) +abs(b.Y -a.Y);
}
double L1distanceSP(const L &s, const P &p){
    double ret = INF;
    for(int i=0; i<2; i++){
        L gl(p, p +P(i, 1-i));
        if(!isParallel(s, gl) && intersectLS(gl, s)){
            P cp = crosspointLL(s, L(p, p+P(i,1-i)));
            ret = min(ret, abs(p -cp));
        }
        ret = min(ret, L1distance(p, s[i]));
    }
    return ret;
}

int in_poly(const P &p, const VP &poly){
    int n = poly.size();
    int cn=0;
    for(int i=0; i<n; i++){
        if(intersectSP(L(poly[i], poly[(i+1)%n]), p)){
            return 0;
        }
    }
    L ray(p, p+P(INF, 0));
    for(int i=0; i<n; i++){
        if((poly[i].Y <= p.Y && poly[(i+1)%n].Y > p.Y) ||
           (poly[i].Y > p.Y && poly[(i+1)%n].Y <= p.Y)){
            if(intersectSS(ray, L(poly[i],poly[(i+1)%n]))){
                cn++;
            }
        }
    }
    if(cn%2!=0) return 1;
    else return -1;
}
vector<L> arrangement(const vector<L> &e){
    VP cp;
    cp.reserve(e.size()*e.size());
    for(int i=0; i<(int)e.size(); i++){
        for(int j=i+1; j<(int)e.size(); j++){
            if(!isParallel(e[i], e[j]) && intersectSS(e[i], e[j])){
                cp.push_back(crosspointLL(e[i], e[j]));
            }
        }
    }
    sort(cp.begin(), cp.end());
    cp.erase(unique(cp.begin(), cp.end()), cp.end());

    vector<L> ret;
    for(int i=0; i<(int)e.size(); i++){
        VP vlist;
        vlist.reserve(e.size());
        for(int j=0; j<(int)cp.size(); j++){
            if(intersectSP(e[i], cp[j])){
                vlist.push_back(cp[j]);
            }
        }
        for(int j=0; j<(int)vlist.size()-1; j++){
            ret.push_back(L(vlist[j], vlist[j+1]));
        }
    }
    sort(ret.begin(), ret.end());
    ret.erase(unique(ret.begin(), ret.end()), ret.end());
    return ret;
}


int main(){
    while(1){
        int n,r;
        cin >> n >> r;
        if(n==0) break;
        
        VP v(n);
        for(int i=0; i<n; i++){
            double x,y;
            cin >> x >> y;
            v[i] = P(x,y);
        }
        vector<VP> sq(n, VP(4));
        for(int i=0; i<n; i++){
            sq[i][0] = v[i] +P(r, 0);
            sq[i][1] = v[i] +P(0, r);
            sq[i][2] = v[i] +P(-r, 0);
            sq[i][3] = v[i] +P(0, -r);
        }

        vector<L> l;
        l.reserve(9*n);
        for(int i=0; i<n; i++){
            l.push_back(L(v[i], v[(i+1)%n]));
            for(int j=0; j<4; j++){
                l.push_back(L(sq[i][j], sq[(i+1)%n][j]));
                l.push_back(L(sq[i][j], sq[i][(j+1)%4]));
            }
        }
        vector<L> cand = arrangement(l);

        double ans = 0;
        for(int i=0; i<(int)cand.size(); i++){
            bool rem = true;
            for(int j=0; j<n; j++){
                P mid = (cand[i][0] +cand[i][1])/2.0;
                if(L1distanceSP(L(v[j], v[(j+1)%n]), mid) +EPS < r || in_poly(mid, v) == -1){
                    rem = false;
                    break;
                }
            }
            if(rem){
                ans += abs(cand[i][1] -cand[i][0]);
            }
        }
        cout << fixed;
        cout << setprecision(10);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 5740
memory_kb: 5296
final_rank: 15

code_snippet: #include<bits/stdc++.h>
#define inf 1<<29
#define linf 1e16
#define eps (1e-5)
#define mod 1000000007
#define pi acos(-1)
#define phi (1.0+sqrt(5))/2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef vector<int> vi;
typedef vector<pii> vpi;
const int dx[8]={1,0,-1,0,1,1,-1,-1};
const int dy[8]={0,1,0,-1,1,-1,1,-1};

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):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);}
  bool operator<(Point p)const{ 
       return x!=p.x ? x<p.x : y<p.y; }
  bool operator==(Point p)const{ 
       return fabs(x-p.x)<eps && fabs(y-p.y)<eps;}

  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1=Point(),Point p2=Point()):p1(p1),p2(p2){}
};
typedef Segment Line;

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);}

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

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

int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b)>eps)return 1;
  if(cross(a,b)<-eps)return -1;
  if(dot(a,b)<-eps)return 2;
  if(a.norm()<b.norm())return -2;
  return 0;
}

bool intersect(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 intersect(Segment s1,Segment s2){
  return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

Point getCrossPointLL(Line a,Line b){
  double A=cross(a.p2-a.p1,b.p2-b.p1);
  double B=cross(a.p2-a.p1,a.p2-b.p1);
  if(abs(A)<eps || abs(B)<eps)return b.p1;
  return b.p1+(b.p2-b.p1)*(B/A);
}

int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Vector a=g[i]-p,b=g[(i+1)%n]-p;
    if(abs(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;
  }
  if(x)return 2;
  return 0;
}

bool merge_if_able(Segment &s,Segment t){
  if(!equals(0.0,cross(s.p2-s.p1,t.p2-t.p1)))return false;
  if(abs(ccw(s.p1,t.p1,s.p2))==1)return false;
  if(ccw(s.p1,s.p2,t.p1)==-2 || ccw(t.p1,t.p2,s.p1)==-2)
    return false;
  s=Segment(min(s.p1,t.p1),max(s.p2,t.p2));
  return true;
}

void merge_segments(vector<Segment> &s){
  for(int i=0;i<s.size();i++)
    if(s[i].p2<s[i].p1)swap(s[i].p2,s[i].p1);
  for(int i=0;i<s.size();i++){
    for(int j=i+1;j<s.size();j++){
      if(merge_if_able(s[i],s[j])){
        s[j--]=s.back();
        s.pop_back();
      }
    }
  }
}

typedef vector<vector<int> > Graph;

Graph SegmentArrangement(vector<Segment> v,vector<Point> &ps){
  for(int i=0;i<v.size();i++){
    ps.push_back(v[i].p1);
    ps.push_back(v[i].p2);
    for(int j=i+1;j<v.size();j++){
      if(!intersect(v[i],v[j]))continue;
      ps.push_back(getCrossPointLL(v[i],v[j]));
    }
  }
  Graph g(ps.size());
  for(int i=0;i<v.size();i++){
    vector<pair<double,int> > list;
    for(int j=0;j<ps.size();j++)
      if(ccw(v[i].p1,v[i].p2,ps[j])==0)
        list.push_back(mp(norm(v[i].p1-ps[j]),j));
    sort(list.begin(),list.end());
    for(int j=0;j+1<list.size();j++){
      int a=list[j].s,b=list[j+1].s;
      g[a].push_back(b);
    }
  }
  return g;
}

int n,r;
Polygon p;
Graph g;
vector<Point> ps;

void init(){
  p.clear();
  ps.clear();
}

vector<Point> getS(Point a){
  vector<Point> res;
  res.pb(Point(a.x+r,a.y));
  res.pb(Point(a.x,a.y+r));
  res.pb(Point(a.x-r,a.y));
  res.pb(Point(a.x,a.y-r));
  return res;
}

double getDis(Segment s,Point a){
  double res=abs(s.p1.x-a.x)+abs(s.p1.y-a.y);
  res=min(res,abs(s.p2.x-a.x)+abs(s.p2.y-a.y));
  Segment t;
  t=Segment(Point(-inf,a.y),Point(inf,a.y)); 
  if(intersect(s,t)){
    Point b=getCrossPointLL(s,t);
    res=min(res,abs(a-b));
  }
  t=Segment(Point(a.x,-inf),Point(a.x,inf)); 
  if(intersect(s,t)){
    Point b=getCrossPointLL(s,t);
    res=min(res,abs(a-b));
  }
  return res;
}

bool check(Point a){
  double dis=inf;
  FOR(i,0,n){
    Segment s(p[i],p[(i+1)%n]);
    dis=min(dis,getDis(s,a));
  }
  return equals(dis,r);
}

bool check(Point a,Point b){
  if(!check(a+(b-a)/2.0))return false;
  if(contains(p,a)!=2)return false;
  if(contains(p,b)!=2)return false;
  return true;
}

double solve(){
  double res=0;
  vector<Segment> vs;
  vector<vector<Point> > vp;
  FOR(i,0,n)vp.pb(getS(p[i]));
  FOR(i,0,n){
    vector<Point> a=vp[i],b=vp[(i+1)%n];
    FOR(j,0,4){
      vs.pb(Segment(a[j],b[j]));
      vs.pb(Segment(a[j],a[(j+1)%4]));
      vs.pb(Segment(b[j],b[(j+1)%4]));
    }
  }
  merge_segments(vs);
  g=SegmentArrangement(vs,ps);
  FOR(i,0,g.size()){
    FOR(j,0,g[i].size()){
      Point a=ps[i],b=ps[g[i][j]];
      if(check(a,b))res+=abs(b-a);
    }
  }
  return res;
}

int main()
{
  while(cin>>n>>r && n){
    init();
    FOR(i,0,n){
      int x,y;
      cin>>x>>y;
      p.pb(Point(x,y));
    }
    pd(solve());
  }
  return 0;
}
accuracy: 1
time_ms: 1220
memory_kb: 4144
final_rank: 9

code_snippet: #include<cstdio>
#include<complex>
#include<vector>
#include<cmath>
#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

//FILE *fp=fopen("ShoreErosion_visu2.htm","w");
//FILE *fp=stderr;
FILE *fp=fopen("ShoreErosion_myans.txt","w");
typedef double Real;

typedef complex<Real> Point;
typedef complex<Real> Vector;
typedef pair<Point,Point> Segment;
typedef pair<Point,Point> Line;
typedef vector<Point> Polygon;

const Real eps=1e-9;
const Real PI=acos(-1.0);

template<class T> bool eq(T a,T b){
	return abs(a-b)<eps;
}
template<class T> int sgn(T a){
	if(eq(a,(Real)0.0)) return 0;
	if(a>0) return 1;
	return -1;
}

Real arg(Point p){
	return atan2(p.imag(),p.real());
}

Real crP(Vector a,Vector b){
	return (conj(a)*b).imag();
}

Real doP(Vector a,Vector b){
	return (conj(a)*b).real();
}

Point iLL(Line l1,Line l2){
	if(sgn(crP(l1.second-l1.first,l2.second-l2.first))==0) return Point(NAN,NAN);
	Point a=l1.first,b=l1.second;
	Point c=l2.first,d=l2.second;
	Real num=crP(c-a,d-a);
	Real den=crP(b-a,d-c);
	return a+(b-a)*num/den;
}

bool onSeg(Point a,Point b,Point c){
	return eq(abs(a-b),abs(a-c)+abs(c-b));
}

bool isPara(Segment s1,Segment s2){
	return sgn(crP(s1.second-s1.first,s2.second-s2.first))==0;
}

bool cmp_lex(const Point &p1,const Point &p2){
	if(sgn(p1.real()-p2.real())!=0){
		if(p1.real()<p2.real()) return true;
		return false;
	}
	return p1.imag()<p2.imag();
}

bool mergeIfAble(Segment &s,Segment t){
	if(sgn(crP(t.first-s.first,s.second-s.first))!=0) return false;
	if(sgn(crP(t.second-s.first,s.second-s.first))!=0) return false;
/*	Point pts[]={t.first,t.second};
	for(int i=0;i<2;i++){
		if(onSeg(s.first,pts[i],s.second)){
			s.second=pts[i];
		}else if(onSeg(s.second,pts[i],s.first)){
			s.first=pts[i];
		}
	}*/
	if(cmp_lex(s.first,s.second)==false) swap(s.first,s.second);
	if(cmp_lex(t.first,t.second)==false) swap(t.first,t.second);
	Segment res=s;
	if(cmp_lex(res.first,t.first)==false) swap(res,t);
	if(cmp_lex(res.second,t.first)==false){
		if(cmp_lex(res.second,t.second)) res.second=t.second;
		s=res;
		return true;
	}
	return false;
}
void mergeSegments(vector<Segment> &segs){
	while(true){
	bool flg=false;
	for(int i=0;i<segs.size();i++){
		for(int j=i+1;j<segs.size();j++){
			if(mergeIfAble(segs[i],segs[j])){
				segs[j--]=segs.back();
				segs.pop_back();
				flg=true;
			}
		}
	}
	if(flg==false) break;
	}
}

struct Segment2:Segment{
	vector<Point> pts;
	Segment2(){}
	Segment2(Segment s):Segment(s){}
};

vector<Segment> segs;
vector<Segment2> segs2;

Polygon poly;
Real R;

const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
Vector dir[4];

void put(Segment seg){
	Point p=seg.first,q=seg.second;
	Real dx=abs((p-q).real()),dy=abs((p-q).imag());
	int rem=dx<dy?0:1;
	for(int i=0;i<4;i++){
		if(i%2!=rem) continue;
		Point p2=p+Point(::dx[i],::dy[i])*R;
		Point q2=q+Point(::dx[i],::dy[i])*R;
		int s=sgn(crP(q-p,q2-q));
		if(s<0) continue;
		segs.push_back(Segment(p2,q2));
	}
}

void put(Point p){
	for(int i=0;i<4;i++){
		int j=(i+1)%4;
		Point a=p+dir[i]*R;
		Point b=p+dir[j]*R;
		segs.push_back(Segment(a,b));
	}
}

Real mDis(Point a,Point b){
	return abs((a-b).real())+abs((a-b).imag());
}

Real mDis(Segment seg,Point p){
	if(onSeg(seg.first,seg.second,p)) return 0;
	Real res=min(mDis(seg.first,p),mDis(seg.second,p));
	for(int i=0;i<2;i++){
		Point q=p+dir[i];
		if(sgn(crP(q-p,seg.second-seg.first))==0) continue;
		Point r=iLL(Segment(p,q),seg);
		if(onSeg(seg.first,seg.second,r)){
			res=min(res,mDis(p,r));
		}
	}
	return res;
}

bool isin(Polygon poly,Point pt){/*ONは判定していない*/
	bool in=false;
	for(int i=0;i<poly.size();i++){
		Point a=poly[i],b=poly[(i+1)%poly.size()];
		a-=pt,b-=pt;
		if(sgn(a.imag()-b.imag())>0) swap(a,b);
		if(sgn(a.imag())<=0&&0<sgn(b.imag())){
			if(sgn(crP(a,b))<0) in=!in;
		}
	}
	return in;
}

Point center;
bool cmp(const Point &p1,const Point &p2){
	if(sgn(doP(p1-center,p2-center))<0) fprintf(stderr,"direction not correct\n");
	return sgn(abs(p1-center)-abs(p2-center))<0;
}

void showP(Point p){
	printf("(%f,%f) ",p.real(),p.imag());
}

vector<Segment> vec;

Real solve(){
	for(int i=0;i<4;i++) dir[i]=Vector(dx[i],dy[i]);
	for(int i=0;i<poly.size();i++){
		put(poly[i]);
	}
	for(int i=0;i<poly.size();i++){
		Point p=poly[i];
		Point q=poly[(i+1)%poly.size()];
		put(Segment(p,q));
	}
/*	for(int i=0;i<poly.size();i++){
		Point p=poly[i];
		for(int j=0;j<4;j++){
			Point q=p+dir[j]*R;
			segs.push_back(Segment(p,q));
		}
	}*/
	mergeSegments(segs);
	for(int i=0;i<segs.size();i++){
		segs2.push_back(Segment2(segs[i]));
	}
/*	for(int i=0;i<segs2.size();i++) for(int j=i+1;j<segs2.size();j++){
		Point a=segs2[i].first,b=segs2[i].second;
		Point c=segs2[j].first,d=segs2[j].second;
	//	if(sgn(crP(b-a,d-c))==0&&sgn(crP(c-a,b-a))==0){
	//		showP(a);showP(b);showP(c);showP(d);
	//		printf("\n");
	//	}
	}*/
	for(int i=0;i<segs2.size();i++) for(int j=i+1;j<segs2.size();j++){
		Segment2 &s1=segs2[i],&s2=segs2[j];
		Point p=iLL(s1,s2);
		if(isnan(p.real())) continue;
		if((!onSeg(s1.first,s1.second,p))||(!onSeg(s2.first,s2.second,p))) continue;
		s1.pts.push_back(p);
		s2.pts.push_back(p);
	}
	for(int i=0;i<segs2.size();i++){
		for(int j=0;j<poly.size();j++){
			Segment edge=Segment(poly[j],poly[(j+1)%poly.size()]);
			Point p=iLL(segs2[i],edge);
			if(isnan(p.real())) continue;
			if((!onSeg(segs2[i].first,segs2[i].second,p))||(!onSeg(edge.first,edge.second,p))){
				continue;
			}
			segs2[i].pts.push_back(p);
		}
	}
	for(int i=0;i<segs2.size();i++){
	//	segs2[i].pts.push_back(segs2[i].first);
	//	segs2[i].pts.push_back(segs2[i].second);
		for(int j=0;j<poly.size();j++){
			for(int k=0;k<4;k++){
				Point p=poly[j]+dir[k]*R;
				if(onSeg(segs2[i].first,segs2[i].second,p)){
					segs2[i].pts.push_back(p);
				}
			}
			Point p=poly[j];
			if(onSeg(segs2[i].first,segs2[i].second,p)){
				segs2[i].pts.push_back(poly[j]);
			}
		}
		center=segs2[i].first;
		sort(segs2[i].pts.begin(),segs2[i].pts.end(),cmp);
		if(!eq(segs2[i].pts.back(),segs2[i].second)) fprintf(stderr,"c\n");
	}
	Real res=0;
	for(int i=0;i<segs2.size();i++){
		for(int j=0;j+1<segs2[i].pts.size();j++){
			Point a=segs2[i].pts[j],b=segs2[i].pts[j+1];
			if(eq(a,b)) continue;
			Point mid=(a+b)/(Real)2.0;
			bool in=isin(poly,mid);
			if(!in) continue;
			bool suc=true;
			for(int k=0;k<poly.size();k++){
				Segment s=Segment(poly[k],poly[(k+1)%poly.size()]);
				Real dis=mDis(s,mid);
				if(sgn(dis-R)<0) suc=false;
			}
			if(!suc) continue;
			bool flg[2]={true,true};
			for(int k=0;k<poly.size();k++){
				Real dis1=mDis(a,poly[k]),dis2=mDis(b,poly[k]);
				if(sgn(dis1-R)<0||sgn(dis2-R)<0) fprintf(stderr,"a\n");
				if(eq(dis1,R)&&eq(dis2,R)){
					Point p=poly[k];
					int s=sgn(crP(b-a,p-a));
					int id=s==-1?0:1;
					flg[id]=false;
				}
			}
			for(int k=0;k<poly.size();k++){
				Segment edge=Segment(poly[k],poly[(k+1)%poly.size()]);
				Real dis1=mDis(edge,a);
				Real dis2=mDis(edge,b);
				if(sgn(dis1-R)<0||sgn(dis2-R)<0) fprintf(stderr,"b\n");
				if(isPara(edge,Segment(a,b))==false) continue;
				if(eq(dis1,R)&&eq(dis2,R)){
					Point p=edge.first;
					int s=sgn(crP(b-a,p-a));
					int id=s==-1?0:1;
					flg[id]=false;
				}
			}
			if(flg[0]==false&&flg[1]==false) continue;
			res+=abs(b-a);
//			fprintf(fp,"ctx.moveTo(%f,%f);\n",a.real()*10+600,a.imag()*10+600);
//			fprintf(fp,"ctx.lineTo(%f,%f);\n",b.real()*10+600,b.imag()*10+600);
//			fprintf(fp,"ctx.stroke();\n");
//			fprintf(fp,"%f %f %f %f\n",a.real(),a.imag(),b.real(),b.imag());
			vec.push_back(Segment(a,b));
		}
	}
	return res;
}

void init(){
	segs.clear();
	segs2.clear();
	poly.clear();
}

void input(){
	int N;
	scanf("%d%lf",&N,&R);
	if(N==0) exit(0);
	for(int i=0;i<N;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		Point p=Point(x,y);
		poly.push_back(p);
	}
}

int main(){
	for(int i=0;i<4;i++) dir[i]=Vector(dx[i],dy[i]);
	while(true){
		init();
		input();
/*			fprintf(fp,"<html>\n<head>\n<script type=\"text/javascript\">\n");
			fprintf(fp,"function draw(){\n");
			fprintf(fp,"var c=document.getElementById(\"canvas\");\n");
			fprintf(fp,"var ctx=c.getContext(\"2d\");\n");
			fprintf(fp,"ctx.beginPath();\n");*/
			Real ans=solve();
	/*		for(int i=0;i<poly.size();i++){
				fprintf(fp,"ctx.moveTo(%f,%f);\n",poly[i].real()*10+600,poly[i].imag()*10+600);
				fprintf(fp,"ctx.lineTo(%f,%f);\n",poly[(i+1)%poly.size()].real()*10+600,
					poly[(i+1)%poly.size()].imag()*10+600);
				fprintf(fp,"ctx.stroke();\n");
			}*/
	/*		fprintf(fp,"}\n");
			fprintf(fp,"</script></head>\n");
			fprintf(fp,"<body onload=\"draw()\">\n");
			fprintf(fp,"<canvas id=\"canvas\" width=\"2000\" height=\"2000\"></canvas>\n");
			fprintf(fp,"</body></html>\n");*/
		//	fclose(fp);

	//	Real ans=solve();
		printf("%.10f\n",ans);
//		bool flg=mergeIfAble(vec[23],vec[25]);
//		if(flg) fprintf(stderr,"true\n");
//		else fprintf(stderr,"false\n");
	}
	return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 1532
final_rank: 3

code_snippet: #include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <unordered_map>
#include <iterator>
#include <assert.h>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define REPS(i,x) for(int i=1;i<=(int)(x);i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RREPS(i,x) for(int i=((int)(x));i>0;i--)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) (container).begin(), (container).end()
#define RALL(container) (container).rbegin(), (container).rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
template<class S, class T> pair<S,T> operator+(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first+t.first, s.second+t.second);}
template<class S, class T> pair<S,T> operator-(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first-t.first, s.second-t.second);}

namespace geom{
#define X real()
#define Y imag()
#define at(i) ((*this)[i])
#define SELF (*this)
	enum {TRUE = 1, FALSE = 0, BORDER = -1};
	typedef int BOOL;
	typedef double R;
	const R INF = 1e12;
	R EPS = 1e-5;
	const R PI = 3.1415926535897932384626;
	inline int sig(const R &x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
	inline BOOL less(const R &x, const R &y) {return sig(x-y) ? x < y : BORDER;}
	typedef complex<R> P;
	inline R norm(const P &p){return p.X*p.X+p.Y*p.Y;}
	inline R inp(const P& a, const P& b){return (conj(a)*b).X;}
	inline R outp(const P& a, const P& b){return (conj(a)*b).Y;}
	inline P unit(const P& p){return p/abs(p);}
	inline P proj(const P &s, const P &t){return t*inp(s, t)/norm(t);}
	inline int ccw(const P &s, const P &t, const P &p, int adv=0){
		int res = sig(outp(t-s, p-s));
		if(res || !adv) return res;
		if(sig(inp(t-s, p-s)) < 0) return -2;	// p-s-t
		if(sig(inp(s-t, p-t)) < 0) return 2;	// s-t-p
		return 0;								// s-p-t
	}
	
	
	struct L : public vector<P>{	// line
		L(const P &p1, const P &p2){this->push_back(p1);this->push_back(p2);}
		L(){}
		inline P dir()const {return at(1) - at(0);}
		BOOL online(const P &p)const {return !sig(outp(p-at(0), dir()));}
	};
	struct S : public L{	// segment
		S(const P &p1, const P &p2):L(p1, p2){}
		inline S(){}
		inline BOOL online(const P &p)const {
			return !sig(outp(p-at(0), dir())) && inp(p-at(0), dir()) > -EPS && inp(p-at(1), -dir()) > -EPS;
			//if(!sig(norm(p - at(0))) || !sig(norm(p - at(1)))) return BORDER;
			//return !sig(abs(at(0)-p) + abs(at(1) - p) - abs(at(0) - at(1)));
		}
	};
	struct G : public vector<P>{
		G(size_type size=0):vector(size){}
		S edge(int i)const {return S(at(i), at(i+1 == size() ? 0 : i+1));}
		inline BOOL contains(const P &p)const {
			R sum = .0;
			REP(i, size()){
				if(S(at(i), at((i+1)%size())).online(p)) return BORDER;	// online
				sum += arg((at(i) - p) / (at((i+1)%size()) - p));
			}
			return !!sig(sum);
		}
	};

	inline P proj(const P &s, const L &t){return t[0] + proj(s-t[0], t[1]-t[0]);}
	inline P reflect(const P &s, const L &t){return (R)2.*proj(s, t) - s;}
	inline S reflect(const S &s, const L &t){return S(reflect(s[0], t), reflect(s[1], t));}
	BOOL intersect(const S &s, const S &t){
		const int p = ccw(t[0], t[1], s[0], 1) * ccw(t[0], t[1], s[1], 1);
		const int q = ccw(s[0], s[1], t[0], 1) * ccw(s[0], s[1], t[1], 1);
		return !(p>0||q>0);
	}
	BOOL intersect(const S &s, const L &l){
		return (sig(outp(l.dir(), s[0]-l[0])) * sig(outp(l.dir(), s[1]-l[0])) < 0);
	}
	
	inline P crosspoint(const L &l, const L &m){
		R A = outp(l.dir(), m.dir()), B = outp(l.dir(), l[1] - m[0]);
		if(!sig(abs(A)) && !sig(abs(B))) return m[0]; // same line
		if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
		return m[0] + B / A * (m[1] - m[0]);
	}
	
	template<class T> void merge(vector<T> &s) {
		REP(i, s.size()) if (s[i][1] < s[i][0]) swap(s[i][0], s[i][1]);
		sort(ALL(s));
		REP(i, s.size())REP(j, i)if(!sig(outp(s[i].dir(), s[j].dir())) && intersect(s[i], s[j])) {
			s[j][1] = max(s[i][1], s[j][1]);
			s.erase(s.begin() + i--);
			break;
		}
	}
	struct Arrangement{
		struct AEdge{
			int u, v, t;
			R cost;
			AEdge(int u=0, int v=0, int t=0, R cost=0)
				:u(u), v(v), t(t), cost(cost){}
		};
		typedef vector<vector<AEdge>> AGraph;
		vector<P> p;
		AGraph g;
		Arrangement(){}
		Arrangement(vector<S> &seg){
			merge(seg);
			int m = seg.size();
			REP(i, m){
				p.push_back(seg[i][0]);
				p.push_back(seg[i][1]);
				REP(j, i) if(sig(outp(seg[i].dir(), seg[j].dir())) && intersect(seg[i], seg[j]) == TRUE)
					p.push_back(crosspoint(seg[i], seg[j]));
			}
			sort(ALL(p)); UNIQUE(p);
			int n=p.size();
			g.resize(n);
			REP(i, m){
				S &s = seg[i];
				vector<pair<R, int>> ps;
				REP(j, n) if(s.online(p[j])) ps.emplace_back(norm(p[j] - s[0]), j);
				sort(ALL(ps));
				REP(j, (int)ps.size()-1){
					const int u=ps[j].second;
					const int v=ps[j+1].second;
					g[u].emplace_back(u, v, 0, abs(p[u] - p[v]));
					g[v].emplace_back(v, u, 0, abs(p[u] - p[v]));
				}
			}
		}
	};
#undef SELF
#undef at
}

using namespace geom;

int f = 0;
namespace std{
	bool operator<(const P &a, const P &b){return sig(a.X-b.X) ? a.X < b.X : a.Y+EPS < b.Y;}
	bool operator==(const P &a, const P &b){return abs(a-b) < EPS;}
	istream& operator>>(istream &is, P &p){R x,y;is>>x>>y;p=P(x, y);return is;}
}


int n;
R r;

R manhattan(const P &p, const P &q){
	return abs(p.X-q.X) + abs(p.Y-q.Y);
}

R manhattan(const S &s, const P &p){
	R r = min(manhattan(s[0], p), manhattan(s[1], p));
	L x(p, p+P(1, 0));
	L y(p, p+P(0, 1));
	if(sig(outp(s.dir(), x.dir())) && intersect(s, x) == TRUE) r = min(r, abs(crosspoint(x, s).X - p.X));
	if(sig(outp(s.dir(), y.dir())) && intersect(s, y) == TRUE) r = min(r, abs(crosspoint(y, s).Y - p.Y));
	return r;
}

int main(int argc, char *argv[]){
	ios::sync_with_stdio(false);
	int T = 0;
	while(cin >> n >> r, n){
		G g(n);
		vector<vector<P>> p(n, vector<P>(4));
		REP(i, n){
			cin >> g[i];
			p[i][0] = g[i] + P(r, 0);
			p[i][1] = g[i] + P(0, r);
			p[i][2] = g[i] + P(-r, 0);
			p[i][3] = g[i] + P(0, -r);
		}
		vector<S> s;
		REP(i, n)REP(j, 4){
			s.emplace_back(p[i][j], p[(i+1)%n][j]);
			s.emplace_back(p[i][j], p[i][(j+1)%4]);
		}
		Arrangement a(s);
		R ans = 0;
		vector<S> anss;
		REP(i, a.g.size())FOR(e, a.g[i])if(e->u < e->v){
			S s(a.p[e->u], a.p[e->v]);
			if(g.contains(s[0]) && [&](){
				REP(j, n) if(manhattan(g.edge(j), (s[0]+s[1])*(R).5) < r - EPS) return 0;
				return 1;
			}()) ans += abs(s.dir());
		}
		printf("%.10f\n", (double)ans);
	}
	return 0;
}
accuracy: 1
time_ms: 1150
memory_kb: 1840
final_rank: 6

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

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;


const D EPS = 1e-8;

int sig(D a, D b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
bool near(P a, P b) {return !sig(norm(a - b));}
namespace std {
  bool operator<(P a, P b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
  bool operator<(L a, L b) {return !near(a.a, b.a) ? a.a < b.a : a.b < b.b;}
}

D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

P vec(L a) {return a.b - a.a;}

enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(P a, P b, P c) {
  if (near(a, c) || near(b, c)) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

bool iLLs(L a, L b) {return sig(det(vec(a), vec(b)));}
bool iLSs(L a, L b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) < 0;}
bool iSS(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}

P pLL(L a, L b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}


D dmPP(P a, P b) {return abs(a.X - b.X) + abs(a.Y - b.Y);}
D dmSP(L s, P p) {
  D res = min(dmPP(s.a, p), dmPP(s.b, p));
  L l = {p, p + P(1, 0)};
  if (iLSs(l, s)) res = min(res, dmPP(p, pLL(l, s)));
  l = (L){p, p + P(0, 1)};
  if (iLSs(l, s)) res = min(res, dmPP(p, pLL(l, s)));
  return res;
}
D dmSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dmSP(a, b.a), dmSP(a, b.b)), min(dmSP(b, a.a), dmSP(b, a.b)));}

int sGP(Pol pol, P p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = pol[(i + 1) % pol.size()] - p;
    if (ccw(p0, p1, 0) == ON) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

vector<L> merge(vector<L> s) {
  rep (i, s.size()) if (s[i].b < s[i].a) swap(s[i].a, s[i].b);
  sort(s.begin(), s.end());
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j]) && !iLLs(s[i], s[j])) {
    s[j].b = max(s[i].b, s[j].b);
    s.erase(s.begin() + i--);
    break;
  }
  return s;
}

vector<vector<int> > sArr(vector<L> s, vector<P> &vp) {
  s = merge(s);
  rep (i, s.size()) {
    vp.push_back(s[i].a);
    vp.push_back(s[i].b);
  }
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i].a, s[i].b, vp[j]) == ON) {
      v.push_back(make_pair(norm(vp[j] - s[i].a), j));
    }
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return g;
}

int main() {
  while (true) {
    int n;
    D r;
    Pol pol;
    cin >> n >> r;
    if (n == 0) break;
    rep (i, n) {
      D x, y;
      cin >> x >> y;
      pol.push_back(P(x, y));
    }
    vector<L> vl;
    rep (i, n) {
      vl.push_back((L){pol[i] + P(r, 0), pol[i] + P(0, r)});
      vl.push_back((L){pol[i] + P(0, r), pol[i] + P(-r, 0)});
      vl.push_back((L){pol[i] + P(-r, 0), pol[i] + P(0, -r)});
      vl.push_back((L){pol[i] + P(0, -r), pol[i] + P(r, 0)});
    }
    rep (i, n) {
      vl.push_back((L){pol[i] + P(r, 0), pol[(i + 1) % n] + P(r, 0)});
      vl.push_back((L){pol[i] + P(0, r), pol[(i + 1) % n] + P(0, r)});
      vl.push_back((L){pol[i] + P(-r, 0), pol[(i + 1) % n] + P(-r, 0)});
      vl.push_back((L){pol[i] + P(0, -r), pol[(i + 1) % n] + P(0, -r)});
    }
    vector<P> vp;
    vector<vector<int>> g = sArr(vl, vp);
    D res = 0;
    rep (i, vp.size()) rep (j, g[i].size()) if (i < g[i][j]) {
      if (sGP(pol, vp[i]) != 1) continue;
      rep (k, n) if (sig(dmSS((L){pol[k], pol[(k + 1) % n]}, (L){vp[i], vp[g[i][j]]}), r) < 0) goto next;
      res += abs(vp[i] - vp[g[i][j]]);
    next:;
    }
    cout << fixed << setprecision(15) << res << endl;
  }
}
accuracy: 1
time_ms: 6860
memory_kb: 1848
final_rank: 17

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

typedef double D;
typedef complex<D> P;
typedef const P &rP;
typedef pair<P,P> seg;

const D EPS = 1e-7;
const D INF = 1e99;

D pi;

namespace std{
	bool operator< (rP a, rP b){
		if(abs(real(a) - real(b)) > EPS){
			return real(a) < real(b);
		}
		return imag(a) < imag(b) - EPS;
	}
}

D dot(rP a, rP b){
	return real(a) * real(b) + imag(a) * imag(b);
}

D cross(rP a, rP b){
	return real(a) * imag(b) - imag(a) * real(b);
}

int ccw(rP a, P b, P c){
	b -= a;
	c -= a;
	D cr = cross(b, c);
	if(abs(cr) > EPS){
		return cr > 0 ? 1 : -1;
	}
	if(dot(b, c) < -EPS){
		return 2;
	}
	if(abs(b) < abs(c) - EPS){
		return -2;
	}
	return 0;
}

int ccw(const seg &s, rP c){
	return ccw(s.first, s.second, c);
}

D distSP2(rP a, rP b, rP c){
	if(dot(b - a, c - a) <= 0.0){ return abs(c - a); }
	if(dot(a - b, c - b) <= 0.0){ return abs(c - b); }
	return abs(cross(b - a, c - a)) / abs(b - a);
}

P intrSS(const seg &a, const seg &b){
	rP pa1 = a.first, pa2 = a.second, pb1 = b.first, pb2 = b.second;
	P da12 = pa2 - pa1;
	P db21 = pb1 - pb2;
	P dab1 = pb1 - pa1;
	D d = cross(da12, db21);
	if(abs(d) > EPS){
		D t = cross(dab1, db21) / d;
		D s = cross(da12, dab1) / d;
		if(-EPS < t && t < 1.0 + EPS && -EPS < s && s < 1.0 + EPS){
			return pa1 + t * da12;
		}
	}
	return P(INF, INF);
}

bool contains(const vector<P> &plg, rP pt){
	int cnt = 0;
	D y = imag(pt);
	for(size_t i = 1; i < plg.size(); ++i){
		if(distSP2(plg[i - 1], plg[i], pt) < EPS){
			return false;
		}
		D dyi = imag(plg[i]) - y;
		D dyj = y - imag(plg[i - 1]);
		D tx = (dyi * real(plg[i - 1]) + dyj * real(plg[i])) / (dyi + dyj);
		if(imag(plg[i]) >= y && imag(plg[i - 1]) < y){
			if(tx < real(pt)){ ++cnt; }
		}
		else if(imag(plg[i]) < y && imag(plg[i - 1]) >= y){
			if(tx < real(pt)){ ++cnt; }
		}
	}
	return (cnt % 2 != 0);
}


bool merge_if_able(seg &s, seg &t){
	if(abs(cross(s.second - s.first, t.second - t.first)) > EPS){
		return false;
	}
	if(abs(ccw(s.first, t.first, s.second)) == 1){
		return false;
	}
	if(ccw(s, t.first) == -2 || ccw(t, s.first) == -2){
		return false;
	}
	s = seg(min(s.first, t.first), max(s.second, t.second));
	return true;
}
void mergeseg(vector<seg> &segs){
	for(size_t i = 0; i < segs.size(); ++i){
		if(segs[i].second < segs[i].first){
			swap(segs[i].first, segs[i].second);
		}
	}
	
	int inc = 1;
	for(size_t i = 0; i < segs.size(); i += inc){
		inc = 1;
		for(size_t j = i + 1; j < segs.size(); ++j){
			if(merge_if_able(segs[i], segs[j])){
				segs[j--] = segs.back();
				segs.pop_back();
				inc = 0;
			}
		}
	}
}

void segarrange(vector<seg> &ss){
	set<P> s_ps;
	for(size_t i = 0; i < ss.size(); ++i){
		s_ps.insert(ss[i].first);
		s_ps.insert(ss[i].second);
		for(size_t j = i + 1; j < ss.size(); ++j){
			P t = intrSS(ss[i], ss[j]);
			if(real(t) != INF){
				s_ps.insert(t);
			}
		}
	}

	vector<P> ps(s_ps.begin(), s_ps.end());
	vector<seg> res;
	for(size_t i = 0; i < ss.size(); ++i){
		vector<pair<D,int> > ls;
		for(size_t j = 0; j < ps.size(); ++j){
			if(ccw(ss[i], ps[j]) == 0){
				ls.push_back(make_pair(abs(ss[i].first - ps[j]), j));
			}
		}
		sort(ls.begin(), ls.end());
		for(size_t j = 0; j + 1 < ls.size(); ++j){
			int a = ls[j].second, b = ls[j + 1].second;
			res.push_back(seg(ps[a], ps[b]));
		}
	}

	ss.swap(res);
}

int segtype1(const seg &s){
	D a = arg(s.second - s.first);
	return min(abs(a - 0.5 * pi), abs(a + 0.5 * pi)) < 0.25 * pi ? 1 : 0;
}

D distPP1(rP a, rP b){
	return abs(real(a) - real(b)) + abs(imag(a) - imag(b));
}

D distSP1(const seg &s, rP p){
	D a[2] = {real(s.first), imag(s.first)};
	D b[2] = {real(s.second), imag(s.second)};
	D c[2] = {real(p), imag(p)};
	int t = segtype1(s);
	if(a[t] > b[t]){
		swap(a[0], b[0]);
		swap(a[1], b[1]);
	}

	if(c[t] < a[t]){
		return distPP1(p, P(a[0], a[1]));
	}
	if(c[t] > b[t]){
		return distPP1(p, P(b[0], b[1]));
	}

	D d = (b[1 - t] - a[1 - t]) / (b[t] - a[t]) * (c[t] - a[t]) + a[1 - t];
	return abs(c[1 - t] - d);
}

int main(){
	pi = acos(-1.0);
	cout << fixed << setprecision(9);

	int n;
	D r, x, y;
	while(cin >> n >> r, n){
		vector<P> plg(n + 1);
		for(int i = 0; i < n; ++i){
			cin >> x >> y;
			plg[i] = P(x, y);
		}
		plg[n] = plg[0];

		P ir(0.0, r);

		vector<seg> segs;
		for(int i = 0; i < n; ++i){
			segs.push_back(seg(plg[i] + r, plg[i] + ir));
			segs.push_back(seg(plg[i] + ir, plg[i] - r));
			segs.push_back(seg(plg[i] - r, plg[i] - ir));
			segs.push_back(seg(plg[i] - ir, plg[i] + r));

			int t = segtype1(seg(plg[i], plg[i + 1]));
			if(t == 0){
				segs.push_back(seg(plg[i] + ir, plg[i + 1] + ir));
				segs.push_back(seg(plg[i] - ir, plg[i + 1] - ir));
			}
			else{
				segs.push_back(seg(plg[i] + r, plg[i + 1] + r));
				segs.push_back(seg(plg[i] - r, plg[i + 1] - r));
			}
		}

		mergeseg(segs);
		segarrange(segs);

		D ans = 0.0;
		for(size_t i = 0; i < segs.size(); ++i){
			P mdp = 0.5 * (segs[i].first + segs[i].second);
			if(contains(plg, mdp)){
				D mindist = INF;
				for(int j = 0; j < n; ++j){
					mindist = min(mindist, distSP1(seg(plg[j], plg[j + 1]), mdp));
				}
				if(abs(mindist - r) < EPS){
					ans += abs(segs[i].second - segs[i].first);
				}
			}
		}
		
		cout << ans << '\n';
	}
}
accuracy: 1
time_ms: 160
memory_kb: 1696
final_rank: 1

code_snippet: #include<iostream>
#include<complex>
#include<queue>
#include<algorithm>
#include<cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;

const D EPS = 1e-8;
const D PI = acos(-1);

inline int sig(const D &a, const D &b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
inline bool near(const P &a, const P &b) {return !sig(norm(a - b));}
namespace std {
  inline bool operator<(const P &a, const P &b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
  inline bool operator<(const L &a, const L &b) {return !near(a.a, b.a) ? a.a < b.a : a.b < b.b;}
}

inline D det(const P &a, const P &b) {return a.X * b.Y - a.Y * b.X;}

inline P vec(const L &a) {return a.b - a.a;}

enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
inline int ccw(const P &a, const P &b, const P &c) {
  if (near(a, c) || near(b, c)) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

inline bool iLLs(const L &a, const L &b) {return sig(det(vec(a), vec(b)));}
inline bool iLSs(const L &a, const L &b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) < 0;}
inline bool iSS(const L &a, const L &b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}

inline P pLL(const L &a, const L &b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}

inline D dmPP(const P &a, const P &b) {return abs(a.X - b.X) + abs(a.Y - b.Y);}
inline D dmSP(const L &s, const P &p) {
  D res = min(dmPP(s.a, p), dmPP(s.b, p));
  L l = {p, p + P(1, 0)};
  if (iLSs(l, s)) res = min(res, dmPP(p, pLL(l, s)));
  l = (L){p, p + P(0, 1)};
  if (iLSs(l, s)) res = min(res, dmPP(p, pLL(l, s)));
  return res;
}
inline D dmSS(const L &a, const L &b) {return iSS(a, b) ? 0 : min(min(dmSP(a, b.a), dmSP(a, b.b)), min(dmSP(b, a.a), dmSP(b, a.b)));}

inline int sGP(const Pol &pol, const P &p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = pol[(i + 1) % pol.size()] - p;
    if (ccw(p0, p1, 0) == ON) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

inline void merge(vector<L> &s) {
  rep (i, s.size()) if (s[i].b < s[i].a) swap(s[i].a, s[i].b);
  sort(s.begin(), s.end());
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j]) && !iLLs(s[i], s[j])) {
    s[j].b = max(s[i].b, s[j].b);
    s.erase(s.begin() + i--);
    break;
  }
}

inline vector<vector<int> > sArr(vector<L> s, vector<P> &vp) {
  merge(s);
  rep (i, s.size()) {
    vp.push_back(s[i].a);
    vp.push_back(s[i].b);
  }
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i].a, s[i].b, vp[j]) == ON) {
      v.push_back(make_pair(norm(vp[j] - s[i].a), j));
    }
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return g;
}

int main() {
  while (true) {
    int n;
    D r;
    cin >> n >> r;
    if (n == 0) break;
    Pol pol(n);
    rep (i, n) cin >> pol[i].X >> pol[i].Y;
    vector<L> vs;
    rep (i, n) rep (j, 4) vs.push_back((L){pol[i] + polar(r, j * PI / 2), pol[(i + 1) % n] + polar(r, j * PI / 2)});
    rep (i, n) rep (j, 4) vs.push_back((L){pol[i] + polar(r, j * PI / 2), pol[i] + polar(r, (j + 1) * PI / 2)});
    vector<P> vp;
    vector<vector<int> > g = sArr(vs, vp);
    D res = 0;
    rep (i, g.size()) rep (j, g[i].size()) {
      L l = (L){vp[i], vp[g[i][j]]};
      rep (i, n) if (sig(r, dmSP((L){pol[i], pol[(i + 1) % n]}, (l.a + l.b) / (D)2)) > 0) goto next;
      if (sGP(pol, l.a) < 0) continue;
      res += abs(vec(l));
    next:;
    }
    printf("%.12Lf\n", res / 2);
  }
  return 0;
}
accuracy: 1
time_ms: 5470
memory_kb: 1808
final_rank: 14

code_snippet: #include<algorithm>
#include<complex>
#include<cstdio>
#include<iostream>
#include<queue>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)
template<class T> T at(vector<T> v, int i) {return v[i % v.size()];}

#define X real()
#define Y imag()

typedef double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;

const D EPS = 1e-6;
const D PI = acos(-1);

// テヲツッツ氾ィツシツεゥツ鳴「テヲツ閉ー
int sig(D a, D b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
bool near(P a, P b) {return !sig(norm(a - b));}
namespace std {
  bool operator<(P a, P b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
  bool operator<(L a, L b) {return !near(a.a, b.a) ? a.a < b.a : a.b < b.b;}
}

// テ・ツ、ツ姪ァツゥツ?
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// テァツキツ堙・ツ按?」ツ?ョテ」ツδ凖」ツつッテ」ツδ暗」ツδォ
P vec(L a) {return a.b - a.a;}

// テァツキツ堙・ツ按?bテ」ツ?ォテ・ツッツセテ」ツ?凖」ツつ凝ァツつケcテ」ツ?ョテ、ツスツ催ァツスツョ
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(P a, P b, P c) {
  if (near(a, c) || near(b, c)) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

// テ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
bool iLLs(L a, L b) {return sig(det(vec(a), vec(b)));}
bool iLSs(L a, L b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) < 0;}
bool iSS(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}

// テ、ツコツ、テァツつケ
P pLL(L a, L b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}

// テ・ツ、ツ堙ィツァツ津・ツスツ「テ」ツ?ョテ・ツ??・ツ、ツ姪・ツ按、テ・ツョツ?テ・ツ??ゥツδィ:1テ」ツ??・ツ堕ィテ、ツクツ?0テ」ツ??・ツ、ツ姪ゥツδィ:-1
int sGP(Pol pol, P p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = at(pol, i + 1) - p;
    if (ccw(p0, p1, 0) == ON) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

// テァツキツ堙・ツ按?」ツつ津」ツδ榲」ツδシテ」ツつクテ」ツ?凖」ツつ?
vector<L> merge(vector<L> s) {
  rep (i, s.size()) if (s[i].b < s[i].a) swap(s[i].a, s[i].b);
  sort(s.begin(), s.end());
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j]) && !iLLs(s[i], s[j])) {
    s[j].b = max(s[i].b, s[j].b);
    s.erase(s.begin() + i--);
    break;
  }
  return s;
}

// テァツキツ堙・ツ按?」ツつ「テ」ツδャテ」ツδウテ」ツつクテ」ツδ。テ」ツδウテ」ツδ?テゥツ堋」テ」ツ?ョテァツつケテ」ツ?クテ」ツ?ョティツセツコテ」ツ?ョテ」ツ?ソテ」ツつ津ヲツ個?」ツ?、
vector<vector<int> > sArr(vector<L> s, vector<P> &vp) {
  s = merge(s);
  rep (i, s.size()) {
    vp.push_back(s[i].a);
    vp.push_back(s[i].b);
  }
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i].a, s[i].b, vp[j]) == ON) {
      v.push_back(make_pair(norm(vp[j] - s[i].a), j));
    }
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return g;
}

// テ」ツδ榲」ツδウテ」ツδ湘」ツδε」ツつソテ」ツδウティツキツ敕ゥツ崢「
D dmPP(P a, P b) {return abs(a.X - b.X) + abs(a.Y - b.Y);}
D dmSP(L s, P p) {
  D res = min(dmPP(s.a, p), dmPP(s.b, p));
  L l = {p, p + P(1, 0)};
  if (iLSs(l, s)) res = min(res, dmPP(p, pLL(l, s)));
  l = (L){p, p + P(0, 1)};
  if (iLSs(l, s)) res = min(res, dmPP(p, pLL(l, s)));
  return res;
}
D dmSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dmSP(a, b.a), dmSP(a, b.b)), min(dmSP(b, a.a), dmSP(b, a.b)));}

int main() {
  while (true) {
    int n;
    D r;
    cin >> n >> r;
    if (n == 0) break;
    Pol pol(n);
    rep (i, n) cin >> pol[i].X >> pol[i].Y;
    vector<L> s;
    rep (i, n) rep (j, 4) s.push_back((L){pol[i] + polar(r, j * PI / 2), at(pol, i + 1) + polar(r, j * PI / 2)});
    rep (i, n) rep (j, 4) s.push_back((L){pol[i] + polar(r, j * PI / 2), pol[i] + polar(r, (j + 1) * PI / 2)});
    vector<P> vp;
    vector<vector<int> > edge = sArr(s, vp);
    D res = 0;
    rep (i, edge.size()) if (sGP(pol, vp[i]) > 0) rep (j, edge[i].size()) {
	D dis = 1e9;
	rep (k, n) dis = min(dis, dmSS((L){pol[k], at(pol, k + 1)}, (L){vp[i], vp[edge[i][j]]}));
	if (sig(dis, r) < 0) continue;
	res += abs(vp[i] - vp[edge[i][j]]);
      }
    printf("%.12f\n", res / 2);
  }
  return 0;
}
accuracy: 1
time_ms: 4010
memory_kb: 1580
final_rank: 13

code_snippet: #include<iostream>
#include<complex>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
typedef pair<P, P> L;
typedef vector<P> Pol;

const D INF = 1e40;
const D EPS = 1e-8;
const D PI = acos(-1);

int sig(D r) {return (r < -EPS) ? -1 : (r > EPS) ? 1 : 0;}
bool eq(D a, D b) {return abs(a - b) < EPS;}
bool near(P a, P b) {return abs(a - b) < EPS;}

// 内積
D dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// 外積
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// 線分のベクトル
P vec(L a) {return a.second - a.first;}

// 線分abに対する点xの位置
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(L s, P p) {
  P a = vec(s);
  p -= s.first;
  D cr = det(a, p);
  if (eq(cr, 0)) {
    if (sig(dot(a, p)) < 0) return BACK;
    if (sig(norm(a) - norm(p)) < 0) return FRONT;
    return ON;
  }
  return (cr > 0) ? LEFT : RIGHT;
}

// 交差判定
bool iLL(L a, L b) {return !eq(det(vec(a), vec(b)), 0);}
bool iLS(L a, L b) {return sig(det(vec(a), b.first - a.first)) * sig(det(vec(a), b.second - a.first)) <= 0;}
bool iSS(L a, L b) {
  int cwa = ccw(a, b.first) | ccw(a, b.second);
  int cwb = ccw(b, a.first) | ccw(b, a.second);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}

// 交点
P pLL(L a, L b) {return a.first + vec(a) * (det(vec(b), b.first - a.first) / det(vec(b), vec(a)));}

// 比較関数
namespace std {
  bool operator<(P a, P b) {return eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X;}
}

// 多角形の内外判定 内部:1、周上:0、外部:-1
int sGP(Pol pol, P p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = pol[(i + 1) % pol.size()] - p;
    if (sig(det(p0, p1)) == 0 && sig(dot(p0, p1)) <= 0) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

// 線分をマージする
vector<L> merge(vector<L> s) {
  rep (i, s.size()) if (s[i].second < s[i].first) swap(s[i].first, s[i].second);
  sort(s.begin(), s.end());
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j]) && !iLL(s[i], s[j])) {
    s[j].second = max(s[i].second, s[j].second);
    s.erase(s.begin() + i--);
    break;
  }
  return s;
}

// 線分アレンジメント 隣の点への辺のみを持つ
pair<vector<P>, vector<vector<int> > > sArr(vector<L> s) {
  s = merge(s);
  vector<P> vp;
  rep (i, s.size()) {
    vp.push_back(s[i].first);
    vp.push_back(s[i].second);
  }
  rep (i,s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i], vp[j]) == ON) v.push_back(make_pair(norm(vp[j] - s[i].first), j));
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return make_pair(vp, g);
}

D dmPP(P a, P b) {return abs(a.X - b.X) + abs(a.Y - b.Y);}

D dmSP(L s, P p) {
  D res = min(dmPP(s.first, p), dmPP(s.second, p));
  L l = L(p, p + P(1, 0));
  if (iLS(l, s) && !eq(det(vec(l), vec(s)), 0)) {
    P pp = pLL(l, s);
    res = min(res, dmPP(p, pp));
  }
  l = L(p, p + P(0, 1));
  if (iLS(l, s) && !eq(det(vec(l), vec(s)), 0)) {
    P pp = pLL(l, s);
    res = min(res, dmPP(p, pp));
  }
  return res;
}

D dmSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dmSP(a, b.first), dmSP(a, b.second)), min(dmSP(b, a.first), dmSP(b, a.second)));}

int dx[] = {1, 0, -1, 0, 1};
int dy[] = {0, 1, 0, -1, 0};

int main() {
  int n;
  D r;
  while (true) {
    cin >> n >> r;
    if (n == 0 && r == 0) break;
    Pol pol;
    rep (i, n) {
      P p;
      cin >> p.X >> p.Y;
      pol.push_back(p);
    }
    vector<L> segs;
    rep (i, n) rep (j, 4) segs.push_back(L(pol[i] + r * P(dx[j], dy[j]), pol[i] + r * P(dx[j + 1], dy[j + 1])));
    rep (i, n) rep (j, 4) segs.push_back(L(pol[i] + r * P(dx[j], dy[j]), pol[(i + 1) % n] + r * P(dx[j], dy[j])));
    pair<vector<P>, vector<vector<int> > > arr = sArr(segs);
    D res = 0;
    rep (i, arr.first.size()) {
      if (sGP(pol, arr.first[i]) <= 0) continue;
      rep (j, arr.second[i].size()) {
	L seg(arr.first[i], arr.first[arr.second[i][j]]);
	bool ok = true;
	rep (k, n) {
	  if (sig(r - dmSS(seg, L(pol[k], pol[(k + 1) % n]))) > 0) {
	    ok = false;
	    break;
	  }
	}
	if (ok) {
	  res += abs(vec(seg));
	}
      }
    }
    printf("%.12Lf\n", res / 2);
  }
  return 0;
}
accuracy: 1
time_ms: 1570
memory_kb: 2072
final_rank: 7

code_snippet: #include<iostream>
#include<complex>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
typedef pair<P, P> L;
typedef vector<P> Pol;

const D INF = 1e40;
const D EPS = 1e-8;
const D PI = acos(-1);

int sig(D r) {return (r < -EPS) ? -1 : (r > EPS) ? 1 : 0;}
bool eq(D a, D b) {return abs(a - b) < EPS;}
bool near(P a, P b) {return abs(a - b) < EPS;}

// テ・ツ??ァツゥツ?
D dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// テ・ツ、ツ姪ァツゥツ?
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// テァツキツ堙・ツ按?」ツ?ョテ」ツδ凖」ツつッテ」ツδ暗」ツδォ
P vec(L a) {return a.second - a.first;}

// テァツキツ堙・ツ按?bテ」ツ?ォテ・ツッツセテ」ツ?凖」ツつ凝ァツつケxテ」ツ?ョテ、ツスツ催ァツスツョ
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(L s, P p) {
  P a = vec(s);
  p -= s.first;
  D cr = det(a, p);
  if (eq(cr, 0)) {
    if (sig(dot(a, p)) < 0) return BACK;
    if (sig(norm(a) - norm(p)) < 0) return FRONT;
    return ON;
  }
  return (cr > 0) ? LEFT : RIGHT;
}

// テ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
bool iLL(L a, L b) {return !eq(det(vec(a), vec(b)), 0);}
bool iLS(L a, L b) {return sig(det(vec(a), b.first - a.first)) * sig(det(vec(a), b.second - a.first)) <= 0;}
bool iSS(L a, L b) {
  int cwa = ccw(a, b.first) | ccw(a, b.second);
  int cwb = ccw(b, a.first) | ccw(b, a.second);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}

// テ、ツコツ、テァツつケ
P pLL(L a, L b) {return a.first + vec(a) * (det(vec(b), b.first - a.first) / det(vec(b), vec(a)));}

// テヲツッツ氾ィツシツεゥツ鳴「テヲツ閉ー
namespace std {
  bool operator<(P a, P b) {return eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X;}
}

// テ・ツ、ツ堙ィツァツ津・ツスツ「テ」ツ?ョテ・ツ??・ツ、ツ姪・ツ按、テ・ツョツ?テ・ツ??ゥツδィ:1テ」ツ??・ツ堕ィテ、ツクツ?0テ」ツ??・ツ、ツ姪ゥツδィ:-1
int sGP(Pol pol, P p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = pol[(i + 1) % pol.size()] - p;
    if (sig(det(p0, p1)) == 0 && sig(dot(p0, p1)) <= 0) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

// テァツキツ堙・ツ按?」ツつ津」ツδ榲」ツδシテ」ツつクテ」ツ?凖」ツつ?
vector<L> merge(vector<L> s) {
  rep (i, s.size()) if (s[i].second < s[i].first) swap(s[i].first, s[i].second);
  sort(s.begin(), s.end());
  vector<bool> flag;
  rep (i, s.size()) flag.push_back(true);
  rep (i, s.size()) if (flag[i]) rep (j, i) if (flag[j]) {
    if (iSS(s[i], s[j]) && !iLL(s[i], s[j])) {
      s[j].second = s[i].second;
      flag[i] = false;
      break;
    }
  }
  vector<L> segs;
  rep (i, s.size()) if (flag[i]) segs.push_back(s[i]);
  return segs;
}

// テァツキツ堙・ツ按?」ツつ「テ」ツδャテ」ツδウテ」ツつクテ」ツδ。テ」ツδウテ」ツδ?テゥツ堋」テ」ツ?ョテァツつケテ」ツ?クテ」ツ?ョティツセツコテ」ツ?ョテ」ツ?ソテ」ツつ津ヲツ個?」ツ?、
pair<vector<P>, vector<vector<int> > > sArr(vector<L> s) {
  s = merge(s);
  vector<P> vp;
  rep (i, s.size()) {
    vp.push_back(s[i].first);
    vp.push_back(s[i].second);
  }
  rep (i,s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i], vp[j]) == ON) v.push_back(make_pair(norm(vp[j] - s[i].first), j));
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return make_pair(vp, g);
}

D dmPP(P a, P b) {return abs(a.X - b.X) + abs(a.Y - b.Y);}

D dmSP(L s, P p) {
  D res = min(dmPP(s.first, p), dmPP(s.second, p));
  L l = L(p, p + P(1, 0));
  if (iLS(l, s) && !eq(det(vec(l), vec(s)), 0)) {
    P pp = pLL(l, s);
    res = min(res, dmPP(p, pp));
  }
  l = L(p, p + P(0, 1));
  if (iLS(l, s) && !eq(det(vec(l), vec(s)), 0)) {
    P pp = pLL(l, s);
    res = min(res, dmPP(p, pp));
  }
  return res;
}

D dmSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dmSP(a, b.first), dmSP(a, b.second)), min(dmSP(b, a.first), dmSP(b, a.second)));}

int dx[] = {1, 0, -1, 0, 1};
int dy[] = {0, 1, 0, -1, 0};

int main() {
  int n;
  D r;
  while (true) {
    cin >> n >> r;
    if (n == 0 && r == 0) break;
    Pol pol;
    rep (i, n) {
      P p;
      cin >> p.X >> p.Y;
      pol.push_back(p);
    }
    vector<L> segs;
    rep (i, n) rep (j, 4) segs.push_back(L(pol[i] + r * P(dx[j], dy[j]), pol[i] + r * P(dx[j + 1], dy[j + 1])));
    rep (i, n) rep (j, 4) segs.push_back(L(pol[i] + r * P(dx[j], dy[j]), pol[(i + 1) % n] + r * P(dx[j], dy[j])));
    pair<vector<P>, vector<vector<int> > > arr = sArr(segs);
    D res = 0;
    rep (i, arr.first.size()) {
      if (sGP(pol, arr.first[i]) <= 0) continue;
      rep (j, arr.second[i].size()) {
	L seg(arr.first[i], arr.first[arr.second[i][j]]);
	bool ok = true;
	rep (k, n) {
	  if (sig(r - dmSS(seg, L(pol[k], pol[(k + 1) % n]))) > 0) {
	    ok = false;
	    break;
	  }
	}
	if (ok) {
	  res += abs(vec(seg));
	}
      }
    }
    printf("%.12Lf\n", res / 2);
  }
  return 0;
}
accuracy: 1
time_ms: 1580
memory_kb: 2080
final_rank: 8