Problem:
Solar Car
Alice and Bob are playing a game of baggage delivery using a toy solar car. A number of poles
are placed here and there in the game field.
At the start of a game, the solar car is placed right next to a pole, and the same or another pole is marked as the destination. Bob chooses one of the poles and places the baggage there. Then, Alice plans a route of the car to pick up the baggage and deliver it to the marked destination. Alice chooses the shortest possible route and Bob should choose a pole to maximize the route length.
The solar car can drive arbitrary routes but, as it has no battery cells, it would stop as soon as it gets into shadows. In this game, a point light source is located on the surface of the field, and thus the poles cast infinitely long shadows in the directions opposite to the light source location. The drive route should avoid any of these shadows.
When the initial positions of the solar car and the destination are given, assuming that both
players make the best choices, the length of the drive route is uniquely determined.
Let us think of all the possible game configurations with given two sets of poles, one for the start positions of the solar car and the other for the destinations. When both the initial car position and the destination are to be chosen uniformly at random from the corresponding sets, what is the expected route length?
Your task is to compute the expected value of the route length, given the set of the initial
positions of the car and that of the destinations.
Input
The input consists of a single test case of the following format.
$n$
$x_1$ $y_1$
...
$x_n$ $y_n$
$p$
$a_1$ $b_1$ $c_1$ $d_1$
...
$a_p$ $b_p$ $c_p$ $d_p$
Here, $n$ is the number of poles ($3 \leq n \leq 2000$). The poles are numbered 1 through $n$ and the $i$-th pole is placed at integer coordinates ($x_i$, $y_i$) ($-1000 \leq x_i \leq 1000, -1000 \leq y_i \leq 1000$). The point light is at (0, 0). Poles are not placed at (0, 0) nor in a shadow of another pole, and no two poles are placed at the same coordinates.
$p$ is the number of pairs of sets ($1 \leq p \leq 10^5$). The $i$-th pair of sets is specified by four integers ($a_i, b_i, c_i, d_i$) ($1 \leq a_i \leq b_i \leq n, 1 \leq c_i \leq d_i \leq n$). Specifically, the solar car is initially placed at the $j$-th pole, with $j$ chosen uniformly at random from $\{a_i, ...,  b_i\}$, and the destination pole is also chosen uniformly at random from $\{c_i, ..., d_i\}$.
Output
Output the answer for each pair of sets. Absolute or relative errors less than $10^{-7}$ are permissible.
Sample Input 1
5
7 0
3 3
0 7
-3 3
-7 0
6
1 1 3 3
3 3 4 4
1 1 5 5
5 5 2 2
2 2 4 4
1 5 1 5
Sample Output 1
24.000000000000
20.440306508911
20.000000000000
19.000000000000
15.440306508911
21.606571644990
For the first set pair of this test case, the solar car is placed at (7, 0) and the 
flag is placed at (0, 7). Then, Bob places the baggage at (-7, 0). The length of the shortest route from (-7, 0) to (0, 7) is 10
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i,n) for(ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template <class A, class B> void chmax(A& l, const B& r){ if(l < r) l = r; }
template <class A, class B> void chmin(A& l, const B& r){ if(r < l) l = r; }

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;
int sgn(D a){ return (a < -EPS) ? -1 : (a > EPS); }
int sgn(D a, D b){ return sgn(a - b); }
struct P {
  D x, y;
  P(D x = D(), D y = D()) : x(x), y(y) {}
  P operator+(P r) const { return { x + r.x, y + r.y }; }
  P operator-(P r) const { return { x - r.x, y - r.y }; }
  P operator*(P r) const {
    return {x * r.x - y * r.y, x * r.y + y * r.x};
   }
  P operator*(D r) const { return {x * r , y * r}; }
  P operator/(D r) const { return {x / r , y / r}; }
  P& operator+=(P r) { return *this = *this + r; }
  P& operator-=(P r) { return *this = *this - r; }
  P& operator*=(P r) { return *this = *this * r; }
  P& operator*=(D r) { return *this = *this * r; }
  P& operator/=(D r) { return *this = *this / r; }
  P operator-() const { return {-x, -y}; }
  bool operator<(P r) const {
    return 2 * sgn(x, r.x) + sgn(y, r.y) < 0;
  }
  bool operator==(P r) const {
    return sgn((*this - r).rabs()) == 0;
  }
  bool operator!=(P r) const { return !(*this == r); }
  D norm() const { return x * x + y * y; }
  D abs() const { return sqrt(norm()); }
  D rabs() const {
    return max(std::abs(x), std::abs(y));
  }
  D arg() const { return atan2(y, x); }
  pair<D, D> to_pair() const { return {x,y}; }
  static P polar(D le, D th){
    return{le * cos(th), le * sin(th)};
  }
};
ostream& operator<<(ostream& os, const P& p){
  return os << "P(" << p.x << ", " << p.y << ")";
}
bool ccw(P a, P b){
  return a.x * b.y - a.y * b.x >= -EPS;
}

V<V<D>> disttab(ll N, V<P> A){
  V<P> B(N*2); REP(i,N) B[i] = B[i+N] = A[i];
  V<V<D>> ans(N, V<D>(N));
  REP(s,N){
    D sum = 0;
    V<P> st;
    st.push_back(A[s]);
    auto x = B[s];
    for(ll t=1; t<N; t++){
      auto y = B[s+t];
      if(!ccw(x, y)) break;
      while(st.size() >= 2){
        auto m = st.back(); st.pop_back();
        auto l = st.back();
        if(!ccw(m-l, y-l)){ st.push_back(m); break; }
        sum -= (m-l).abs();
      }
      sum += (y-st.back()).abs();
      st.push_back(y);
      ll f = (s + t) % N;
      ans[s][f] = ans[f][s] = sum;
    }
  }
  return ans;
}

V<V<D>> solve(ll N, V<P> A){
  auto G = disttab(N, A);
  V<V<D>> ans(N, V<D>(N));
  auto f = [&](ll a, ll b, ll c){
    if(b-a >= N || c-b >= N) return -1.0e100;
    if(a >= N) a -= N;
    if(b >= N) b -= N;
    if(c >= N) c -= N;
    return G[a][b] + G[b][c];
  };
  ll M = N * 2;
  V<ll> argmax(M); REP(i,M) argmax[i] = i;
  V<V<D>> tmp(M, V<D>(M, -1.0e100));
  for(ll d=1; d<=M; d++){
    for(ll l=0; l+d<M; l++){
      ll r = l + d;
      for(ll i=argmax[l]; i<=argmax[l+1]; i++){
        D t = f(l, i, r);
        if(tmp[l][r] < t){
          tmp[l][r] = t;
          argmax[l] = i;
        }
      }
    }
  }
  REP(i,N) REP(j,N) chmax(ans[i][j], tmp[i][j]);
  REP(i,N) REP(j,N) chmax(ans[i][j], tmp[i][j+N]);
  REP(t,2) REP(i,N) REP(j,N) chmax(ans[i][j], ans[j][i]);
  return ans;
}

void testcase(){
  cout.precision(15); cout << fixed;
  ll N; cin >> N;
  V<P> A(N); REP(i,N) cin >> A[i].x >> A[i].y;
  V<ll> I(N); REP(i,N) I[i] = i;
  sort(I.begin(), I.end(), [&](ll l, ll r){ return A[l].arg() < A[r].arg(); });
  V<P> FA(N); REP(i,N) FA[i] = A[I[i]];
  auto dist = solve(N, FA);

  V<V<D>> imos(N+1, V<D>(N+1));
  REP(i,N) REP(j,N) imos[I[i]+1][I[j]+1] = dist[i][j];
  REP(i,N+1) REP(j,N) imos[i][j+1] += imos[i][j];
  REP(i,N) REP(j,N+1) imos[i+1][j] += imos[i][j];

  ll Q; cin >> Q;
  REP(qi,Q){
    ll a,b,c,d; cin >> a >> b >> c >> d; a--; c--;
    double ans = imos[a][c] - imos[a][d] - imos[b][c] + imos[b][d];
    ans /= (b-a) * (d-c);
    cout << ans << "\n";
  }
}

int main(){
  cin.tie(0)->sync_with_stdio(0);
  testcase();
  return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 191872
final_rank: 2

code_snippet: #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i,n) for(ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template <class A, class B> void chmax(A& l, const B& r){ if(l < r) l = r; }
template <class A, class B> void chmin(A& l, const B& r){ if(r < l) l = r; }

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;
int sgn(D a){ return (a < -EPS) ? -1 : (a > EPS); }
int sgn(D a, D b){ return sgn(a - b); }
struct P {
  D x, y;
  P(D x = D(), D y = D()) : x(x), y(y) {}
  P operator+(P r) const { return { x + r.x, y + r.y }; }
  P operator-(P r) const { return { x - r.x, y - r.y }; }
  P operator*(P r) const {
    return {x * r.x - y * r.y, x * r.y + y * r.x};
   }
  P operator*(D r) const { return {x * r , y * r}; }
  P operator/(D r) const { return {x / r , y / r}; }
  P& operator+=(P r) { return *this = *this + r; }
  P& operator-=(P r) { return *this = *this - r; }
  P& operator*=(P r) { return *this = *this * r; }
  P& operator*=(D r) { return *this = *this * r; }
  P& operator/=(D r) { return *this = *this / r; }
  P operator-() const { return {-x, -y}; }
  bool operator<(P r) const {
    return 2 * sgn(x, r.x) + sgn(y, r.y) < 0;
  }
  bool operator==(P r) const {
    return sgn((*this - r).rabs()) == 0;
  }
  bool operator!=(P r) const { return !(*this == r); }
  D norm() const { return x * x + y * y; }
  D abs() const { return sqrt(norm()); }
  D rabs() const {
    return max(std::abs(x), std::abs(y));
  }
  D arg() const { return atan2(y, x); }
  pair<D, D> to_pair() const { return {x,y}; }
  static P polar(D le, D th){
    return{le * cos(th), le * sin(th)};
  }
};
ostream& operator<<(ostream& os, const P& p){
  return os << "P(" << p.x << ", " << p.y << ")";
}
bool ccw(P a, P b){
  return a.x * b.y - a.y * b.x >= -EPS;
}

V<V<D>> disttab(ll N, V<P> A){
  V<P> B(N*2); REP(i,N) B[i] = B[i+N] = A[i];
  V<V<D>> ans(N, V<D>(N));
  REP(s,N){
    D sum = 0;
    V<P> st;
    st.push_back(A[s]);
    auto x = B[s];
    for(ll t=1; t<N; t++){
      auto y = B[s+t];
      if(!ccw(x, y)) break;
      while(st.size() >= 2){
        auto m = st.back(); st.pop_back();
        auto l = st.back();
        if(!ccw(m-l, y-l)){ st.push_back(m); break; }
        sum -= (m-l).abs();
      }
      sum += (y-st.back()).abs();
      st.push_back(y);
      ll f = (s + t) % N;
      ans[s][f] = ans[f][s] = sum;
    }
  }
  return ans;
}

V<V<D>> solve(ll N, V<P> A){
  auto G = disttab(N, A);
  V<V<D>> ans(N, V<D>(N));
  auto f = [&](ll a, ll b, ll c){
    if(b-a >= N || c-b >= N) return -1.0e100;
    if(a >= N) a -= N;
    if(b >= N) b -= N;
    if(c >= N) c -= N;
    return G[a][b] + G[b][c];
  };
  ll M = N * 2;
  V<ll> argmax(M); REP(i,M) argmax[i] = i;
  V<V<D>> tmp(M, V<D>(M, -1.0e100));
  for(ll d=1; d<=M; d++){
    for(ll l=0; l+d<M; l++){
      ll r = l + d;
      for(ll i=argmax[l]; i<=argmax[l+1]; i++){
        D t = f(l, i, r);
        if(tmp[l][r] < t){
          tmp[l][r] = t;
          argmax[l] = i;
        }
      }
    }
  }
  REP(i,N) REP(j,N) chmax(ans[i][j], tmp[i][j]);
  REP(i,N) REP(j,N) chmax(ans[i][j], tmp[i][j+N]);
  REP(t,2) REP(i,N) REP(j,N) chmax(ans[i][j], ans[j][i]);
  return ans;
}

void testcase(){
  cout.precision(15); cout << fixed;
  ll N; cin >> N;
  V<P> A(N); REP(i,N) cin >> A[i].x >> A[i].y;
  V<ll> I(N); REP(i,N) I[i] = i;
  sort(I.begin(), I.end(), [&](ll l, ll r){ return A[l].arg() < A[r].arg(); });
  V<P> FA(N); REP(i,N) FA[i] = A[I[i]];
  auto dist = solve(N, FA);

  V<V<D>> imos(N+1, V<D>(N+1));
  REP(i,N) REP(j,N) imos[I[i]+1][I[j]+1] = dist[i][j];
  REP(i,N+1) REP(j,N) imos[i][j+1] += imos[i][j];
  REP(i,N) REP(j,N+1) imos[i+1][j] += imos[i][j];

  ll Q; cin >> Q;
  REP(qi,Q){
    ll a,b,c,d; cin >> a >> b >> c >> d; a--; c--;
    double ans = imos[a][c] - imos[a][d] - imos[b][c] + imos[b][d];
    ans /= (b-a) * (d-c);
    cout << ans << "\n";
  }
}

int main(){
  cin.tie(0)->sync_with_stdio(0);
  testcase();
  return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 192128
final_rank: 3

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myrand(ll B){
    return (ull)rng() % B;
}

struct point{
    int x,y;
    int id;
    point() {}
    point(int x,int y) : x(x),y(y) {}
    point operator- (point p){
        return point(x-p.x, y-p.y);
    }
    double dist(point p){
        return sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
    }
};
int cross(point a, point b){
    return a.x*b.y - a.y*b.x;
}
int arg_area(point p){
    if(p.y < 0) return 2;
    else if(p.x < 0) return 1;
    else return 0;
}
// 整数範囲の偏角ソート　同一点ないと仮定
// 同一偏角の場合は原点に近い方を優先
bool arg_comp(point a, point b){
    int ap = arg_area(a), bp = arg_area(b);
    if(ap != bp) return ap < bp;
    auto crs = cross(a, b);
    if(crs == 0) return abs(a.x)+abs(a.y) < abs(b.x)+abs(b.y);
    else return crs > 0;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i].x >> p[i].y;
        p[i].id = i;
    }
    // 偏角ソート
    sort(p.begin(), p.end(), [&](auto i,auto j){
        return arg_comp(i, j);
    });

    vector<vector<double>> d(n,vector<double>(n));
    for (int i = 0; i < n; ++i) {
        int k = i;
        double sum = 0;
        vector<int> convex = {i};
        for (int j = 1; j < n; ++j) {
            k++; if(k == n) k = 0;
            if(cross(p[i], p[k]) < 0) break;
            while(convex.size() >= 2){
                int pre = convex.back();
                int s = convex[convex.size()-2];
                if(cross(p[k]-p[s], p[pre]-p[s]) <= 0){
                    convex.pop_back();
                    sum -= p[pre].dist(p[convex.back()]);
                }
                else break;
            }
            sum += p[k].dist(p[convex.back()]);
            convex.push_back(k);
            d[p[i].id][p[k].id] = d[p[k].id][p[i].id] = sum;
        }
    }
    vector<vector<double>> res(n,vector<double>(n));
//    O(N^3)
//    for (int i = 0; i < n; ++i) {
//        for (int j = 0; j < n; ++j) {
//            double mx = 0;
//            for (int k = 0; k < n; ++k) {
//                mx = max(mx, d[i][k]+d[k][j]);
//            }
//            res[i][j] = mx;
//        }
//    }
    vector<vector<int>> t(n,vector<int>(n));
    // i->t[i][j]->j 偏角ソート順で、最短経路が最長となるような中継点
    // t[i][i] = i で初期化
    // t[i-1][j] <= t[i][j] <= t[i][j+1] を利用
    for (int i = 0; i < n; ++i) {
        t[i][i] = i;
    }
    for (int l = 1; l < n; ++l) {
        for (int j = 0; j < n; ++j) {
            int i = (j+l)%n;
            int k = t[(i-1+n)%n][j];
            while(1){
                double dis = d[p[i].id][p[k].id] + d[p[k].id][p[j].id];
                if(res[p[i].id][p[j].id] < dis){
                    res[p[i].id][p[j].id] = dis;
                    t[i][j] = k;
                }
                if(k == t[i][(j+1)%n]) break;
                k++; if(k == n) k = 0;
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            res[i][i] = max(res[i][i], d[i][j]+d[j][i]);
            double mx = max(res[i][j], res[j][i]);
            res[i][j] = res[j][i] = mx;
        }
    }
    vector<vector<double>> sum(n+1,vector<double>(n+1));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i+1][j+1] = res[i][j];
        }
    }
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i][j+1] += sum[i][j];
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j <= n; ++j) {
            sum[i+1][j] += sum[i][j];
        }
    }
    auto query = [&](int a,int b,int c,int d)->double{
        int cnt = (b-a+1)*(d-c+1);
        double s = sum[b][d] - sum[a-1][d] - sum[b][c-1] + sum[a-1][c-1];
        return s/(double)cnt;
    };
    int q; cin >> q;
    while(q--){
        int a,b,c,d; cin >> a >> b >> c >> d;
        printf("%.9f\n", query(a,b,c,d));
    }
}
accuracy: 1
time_ms: 370
memory_kb: 112944
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myrand(ll B){
    return (ull)rng() % B;
}

struct point{
    int x,y;
    point() {}
    point(int x,int y) : x(x),y(y) {}
    point operator- (point p){
        return point(x-p.x, y-p.y);
    }
    double dist(point p){
        return sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
    }
};
int cross(point a, point b){
    return a.x*b.y - a.y*b.x;
}
int arg_area(point p){
    if(p.y < 0) return 2;
    else if(p.x < 0) return 1;
    else return 0;
}
// 整数範囲の偏角ソート　同一点ないと仮定
// 同一偏角の場合は原点に近い方を優先
bool arg_comp(point a, point b){
    int ap = arg_area(a), bp = arg_area(b);
    if(ap != bp) return ap < bp;
    auto crs = cross(a, b);
    if(crs == 0) return abs(a.x)+abs(a.y) < abs(b.x)+abs(b.y);
    else return crs > 0;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i].x >> p[i].y;
    }
    vector<int> idx(n);
    { // 偏角ソート
        vector<pair<point,int>> v(n);
        for (int i = 0; i < n; ++i) {
            v[i].first = p[i];
            v[i].second = i;
        }
        sort(v.begin(), v.end(), [&](auto i,auto j){
            return arg_comp(i.first, j.first);
        });
        for (int i = 0; i < n; ++i) {
            idx[i] = v[i].second;
        }
    }
    vector<vector<double>> d(n,vector<double>(n));
    for (int _i = 0; _i < n; ++_i) {
        int i = idx[_i];
        int id = _i;
        double sum = 0;
        vector<int> convex = {i};
        for (int j = 1; j < n; ++j) {
            id++; if(id == n) id = 0;
            int k = idx[id];
            if(cross(p[i], p[k]) < 0) break;
            while(convex.size() >= 2){
                int pre = convex.back();
                int s = convex[convex.size()-2];
                if(cross(p[k]-p[s], p[pre]-p[s]) <= 0){
                    convex.pop_back();
                    sum -= p[pre].dist(p[convex.back()]);
                }
                else break;
            }
            sum += p[k].dist(p[convex.back()]);
            convex.push_back(k);
            d[i][k] = d[k][i] = sum;
        }
    }
    vector<int> kouho;
    {
        for(int _=0;_<100000;_++){
            int i = myrand(n);
            int j = myrand(n);
            if(i == j) continue;
            int k = 0;
            for(int l=0;l<n;l++){
                if(d[i][l]+d[l][j] > d[i][k]+d[k][j]){
                    k = l;
                }
            }
            kouho.push_back(k);
        }
    }
    sort(kouho.begin(), kouho.end());
    kouho.erase(unique(kouho.begin(), kouho.end()), kouho.end());
    vector<vector<double>> res(n,vector<double>(n));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            double mx = 0;
            for (int k:kouho) {
                mx = max(mx, d[i][k]+d[k][j]);
            }
            res[i][j] = mx;
        }
    }
    vector<vector<double>> sum(n+1,vector<double>(n+1));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i+1][j+1] = res[i][j];
        }
    }
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i][j+1] += sum[i][j];
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j <= n; ++j) {
            sum[i+1][j] += sum[i][j];
        }
    }
    auto query = [&](int a,int b,int c,int d)->double{
        int cnt = (b-a+1)*(d-c+1);
        double s = sum[b][d] - sum[a-1][d] - sum[b][c-1] + sum[a-1][c-1];
        return s/(double)cnt;
    };
    int q; cin >> q;
    while(q--){
        int a,b,c,d; cin >> a >> b >> c >> d;
        printf("%.9f\n", query(a,b,c,d));
    }
}
accuracy: 0.2891566265060241
time_ms: 2560
memory_kb: 97568
final_rank: 8

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myrand(ll B){
    return (ull)rng() % B;
}

struct point{
    int x,y;
    point() {}
    point(int x,int y) : x(x),y(y) {}
    point operator- (point p){
        return point(x-p.x, y-p.y);
    }
    double dist(point p){
        return sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
    }
};
int cross(point a, point b){
    return a.x*b.y - a.y*b.x;
}
int arg_area(point p){
    if(p.y < 0) return 2;
    else if(p.x < 0) return 1;
    else return 0;
}
// 整数範囲の偏角ソート　同一点ないと仮定
// 同一偏角の場合は原点に近い方を優先
bool arg_comp(point a, point b){
    int ap = arg_area(a), bp = arg_area(b);
    if(ap != bp) return ap < bp;
    auto crs = cross(a, b);
    if(crs == 0) return abs(a.x)+abs(a.y) < abs(b.x)+abs(b.y);
    else return crs > 0;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i].x >> p[i].y;
    }
    vector<int> idx(n);
    { // 偏角ソート
        vector<pair<point,int>> v(n);
        for (int i = 0; i < n; ++i) {
            v[i].first = p[i];
            v[i].second = i;
        }
        sort(v.begin(), v.end(), [&](auto i,auto j){
            return arg_comp(i.first, j.first);
        });
        for (int i = 0; i < n; ++i) {
            idx[i] = v[i].second;
        }
    }
    vector<vector<double>> d(n,vector<double>(n));
    for (int _i = 0; _i < n; ++_i) {
        int i = idx[_i];
        int id = _i;
        double sum = 0;
        vector<int> convex = {i};
        for (int j = 1; j < n; ++j) {
            id++; if(id == n) id = 0;
            int k = idx[id];
            if(cross(p[i], p[k]) < 0) break;
            while(convex.size() >= 2){
                int pre = convex.back();
                int s = convex[convex.size()-2];
                if(cross(p[k]-p[s], p[pre]-p[s]) <= 0){
                    convex.pop_back();
                    sum -= p[pre].dist(p[convex.back()]);
                }
                else break;
            }
            sum += p[k].dist(p[convex.back()]);
            convex.push_back(k);
            d[i][k] = d[k][i] = sum;
        }
    }
    vector<int> kouho;
    {
        for(int _=0;_<10000;_++){
            int i = myrand(n);
            int j = myrand(n);
            if(i == j) continue;
            int k = 0;
            for(int l=0;l<n;l++){
                if(d[i][l]+d[l][j] > d[i][k]+d[k][j]){
                    k = l;
                }
            }
            kouho.push_back(k);
        }
    }
    sort(kouho.begin(), kouho.end());
    kouho.erase(unique(kouho.begin(), kouho.end()), kouho.end());
    vector<vector<double>> res(n,vector<double>(n));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            double mx = 0;
            for (int k:kouho) {
                mx = max(mx, d[i][k]+d[k][j]);
            }
            res[i][j] = mx;
        }
    }
    vector<vector<double>> sum(n+1,vector<double>(n+1));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i+1][j+1] = res[i][j];
        }
    }
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i][j+1] += sum[i][j];
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j <= n; ++j) {
            sum[i+1][j] += sum[i][j];
        }
    }
    auto query = [&](int a,int b,int c,int d)->double{
        int cnt = (b-a+1)*(d-c+1);
        double s = sum[b][d] - sum[a-1][d] - sum[b][c-1] + sum[a-1][c-1];
        return s/(double)cnt;
    };
    int q; cin >> q;
    while(q--){
        int a,b,c,d; cin >> a >> b >> c >> d;
        printf("%.9f\n", query(a,b,c,d));
    }
}
accuracy: 0.2891566265060241
time_ms: 410
memory_kb: 97372
final_rank: 7

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myrand(ll B){
    return (ull)rng() % B;
}

struct point{
    int x,y;
    point() {}
    point(int x,int y) : x(x),y(y) {}
    point operator- (point p){
        return point(x-p.x, y-p.y);
    }
    double dist(point p){
        return sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
    }
};
int cross(point a, point b){
    return a.x*b.y - a.y*b.x;
}
int arg_area(point p){
    if(p.y < 0) return 2;
    else if(p.x < 0) return 1;
    else return 0;
}
// 整数範囲の偏角ソート　同一点ないと仮定
// 同一偏角の場合は原点に近い方を優先
bool arg_comp(point a, point b){
    int ap = arg_area(a), bp = arg_area(b);
    if(ap != bp) return ap < bp;
    auto crs = cross(a, b);
    if(crs == 0) return abs(a.x)+abs(a.y) < abs(b.x)+abs(b.y);
    else return crs > 0;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<point> p(n);
    for (int i = 0; i < n; ++i) {
        cin >> p[i].x >> p[i].y;
    }
    vector<int> idx(n);
    { // 偏角ソート
        vector<pair<point,int>> v(n);
        for (int i = 0; i < n; ++i) {
            v[i].first = p[i];
            v[i].second = i;
        }
        sort(v.begin(), v.end(), [&](auto i,auto j){
            return arg_comp(i.first, j.first);
        });
        for (int i = 0; i < n; ++i) {
            idx[i] = v[i].second;
        }
    }
    vector<vector<double>> d(n,vector<double>(n));
    for (int _i = 0; _i < n; ++_i) {
        int i = idx[_i];
        int id = _i;
        double sum = 0;
        vector<int> convex = {i};
        for (int j = 1; j < n; ++j) {
            id++; if(id == n) id = 0;
            int k = idx[id];
            if(cross(p[i], p[k]) < 0) break;
            while(convex.size() >= 2){
                int pre = convex.back();
                int s = convex[convex.size()-2];
                if(cross(p[k]-p[s], p[pre]-p[s]) <= 0){
                    convex.pop_back();
                    sum -= p[pre].dist(p[convex.back()]);
                }
                else break;
            }
            sum += p[k].dist(p[convex.back()]);
            convex.push_back(k);
            d[i][k] = d[k][i] = sum;
        }
    }
    vector<int> kouho;
    {
        for(int _=0;_<3000;_++){
            int i = myrand(n);
            int j = myrand(n);
            if(i == j) continue;
            int k = 0;
            for(int l=0;l<n;l++){
                if(d[i][l]+d[l][j] > d[i][k]+d[k][j]){
                    k = l;
                }
            }
            kouho.push_back(k);
        }
    }
    sort(kouho.begin(), kouho.end());
    kouho.erase(unique(kouho.begin(), kouho.end()), kouho.end());
    vector<vector<double>> res(n,vector<double>(n));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            double mx = 0;
            for (int k:kouho) {
                mx = max(mx, d[i][k]+d[k][j]);
            }
            res[i][j] = mx;
        }
    }
    vector<vector<double>> sum(n+1,vector<double>(n+1));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i+1][j+1] = res[i][j];
        }
    }
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j < n; ++j) {
            sum[i][j+1] += sum[i][j];
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j <= n; ++j) {
            sum[i+1][j] += sum[i][j];
        }
    }
    auto query = [&](int a,int b,int c,int d)->double{
        int cnt = (b-a+1)*(d-c+1);
        double s = sum[b][d] - sum[a-1][d] - sum[b][c-1] + sum[a-1][c-1];
        return s/(double)cnt;
    };
    int q; cin >> q;
    while(q--){
        int a,b,c,d; cin >> a >> b >> c >> d;
        printf("%.9f\n", query(a,b,c,d));
    }
}
accuracy: 0.2891566265060241
time_ms: 250
memory_kb: 97428
final_rank: 6

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

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

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-6;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

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



ld dist[2000][2000];
ld cop[2000][2000];
ll a[2000][2000];
ll b[2000][2000];

ld sum[2000][2000];
void solve() {
	int n; cin >> n;
	vector<int> x(n), y(n);
	rep(i, n)cin >> x[i] >> y[i];
	vector<ld> t(n);
	rep(i, n) {
		t[i] = atan2l(y[i], x[i]);
	}
	vector<int> copx(n), copy(n);
	vector<pair<ld, int>> vp;
	rep(i, n) {
		vp.push_back({ t[i],i });
	}
	sort(all(vp));
	vector<int> rev(n);
	rep(i, vp.size()) {
		int id = vp[i].second;
		copx[i] = x[id];
		copy[i] = y[id];
		t[i] = vp[i].first;
		rev[id] = i;
	}
	auto calc = [&](int i, int j)->ld {
		int dx = x[j] - x[i];
		int dy = y[j] - y[i];
		return sqrtl(dx * dx + dy * dy);
	};
	swap(x, copx);
	swap(y, copy);

	auto isleft = [&](int i, int j, int k)->bool {
		int x1 = x[j] - x[i];
		int x2 = x[k] - x[i];
		int y1 = y[j] - y[i];
		int y2 = y[k] - y[i];
		int val = x1 * y2 - x2 * y1;
		return val >= 0;
	};
	rep(i, n) {
		dist[i][i] = 0;
		vector<int> vl, vr;
		for (int j = 1; j < n; j++) {
			int id = (i + j) % n;
			ld theta = t[id] - t[i];
			while (theta < 0)theta += 2 * pi;
			while (theta >= 2 * pi)theta -= 2 * pi;
			if (theta <= pi) {
				vl.push_back(id);
			}
			else {
				vr.push_back(id);
			}
		}
		reverse(all(vr));
		if (vl.size()) {
			vector<int> vcur;
			vcur.push_back(i);
			vcur.push_back(vl[0]);
			dist[i][vl[0]] = calc(i, vl[0]);
			ld sum = calc(i, vl[0]);
			for (int j = 1; j < vl.size(); j++) {
				while (vcur.size() >= 2 && isleft(vcur[vcur.size() - 2], vcur[vcur.size() - 1], vl[j])) {
					sum -= calc(vcur[vcur.size() - 2], vcur[vcur.size() - 1]);
					vcur.pop_back();
				}
				vcur.push_back(vl[j]);
				sum += calc(vcur[vcur.size() - 2], vcur[vcur.size() - 1]);
				dist[i][vl[j]] = sum;
			}
		}
		if (vr.size()) {
			vector<int> vcur;
			vcur.push_back(i);
			vcur.push_back(vr[0]);
			dist[i][vr[0]] = calc(i, vr[0]);
			ld sum = calc(i, vr[0]);
			for (int j = 1; j < vr.size(); j++) {
				while (vcur.size() >= 2 && !isleft(vcur[vcur.size() - 2], vcur[vcur.size() - 1], vr[j])) {
					sum -= calc(vcur[vcur.size() - 2], vcur[vcur.size() - 1]);
					vcur.pop_back();
				}
				vcur.push_back(vr[j]);
				sum += calc(vcur[vcur.size() - 2], vcur[vcur.size() - 1]);
				dist[i][vr[j]] = sum;
			}
		}
	}
	/*rep(i, n)rep(j,n) {
		cout <<i<<" "<<j<<" "<< dist[i][j] << "\n";
	}*/
	rep(i, n)rep(j, n) {
		cop[i][j] = dist[i][j];
	}
	ld ex = 100000000000000;
	rep(i, n)rep(j, n) {
		dist[i][j] = cop[rev[i]][rev[j]];
		a[i][j] = ex * dist[i][j];
	}
	rep(i, n)Rep(j, i + 1, n) {
		b[i][j] = 0;
	}
	rep(k, n)rep(i, n)Rep(j, i, n) {
		b[i][j] = max(b[i][j], a[k][i] + a[k][j]);
	}
	rep(i, n)Rep(j, i, n) {
		cop[i][j] = b[i][j] / ex;
	}
	rep(i, n)rep(j, i)cop[i][j] = cop[j][i];
	rep(i, n)rep(j, n) {
		sum[i][j] = cop[i][j];
		if (i > 0)sum[i][j] += sum[i - 1][j];
		if (j > 0)sum[i][j] += sum[i][j - 1];
		if (i > 0 && j > 0)sum[i][j] -= sum[i - 1][j - 1];
	}
	auto calc_sum = [&](int lx, int ly, int rx, int ry) {
		ld res = sum[rx][ry];
		if (lx > 0)res -= sum[lx - 1][ry];
		if (ly > 0)res -= sum[rx][ly - 1];
		if (lx > 0 && ly > 0)res += sum[lx - 1][ly - 1];
		return res;
	};
	int q; cin >> q;
	rep(i, q) {
		int a, b, c, d; cin >> a >> b >> c >> d; a--; b--; c--; d--;
		ld ans = calc_sum(a, c, b, d);
		int z = (b - a + 1) * (d - c + 1);
		ans /= (ld)z;
		cout << ans << "\n";
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//expr();

	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 2280
memory_kb: 164104
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define Fi first
#define Se second
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define szz(x) (int)(x).size()
#define rep(i, n) for(int i=0;i<(n);i++)
typedef tuple<int, int, int> t3;

pii operator-(pii a, pii b) { return {a.Fi - b.Fi, a.Se - b.Se}; }
ll operator/(pii a, pii b) { return (ll)a.Fi * b.Se - (ll)a.Se * b.Fi; }

using ppi = pair<pii, int>;
using FL = long double;
FL dist(pii a) { return hypotl(a.Fi, a.Se); }
ppi P[2020];
FL D[2020][2020], F[2020][2020], S[2020][2020];
int fv[2020][2020];
int N;

int main() {
	scanf("%d", &N);
	rep(i, N) {
		int x, y;
		scanf("%d%d", &x, &y);
		P[i] = {{x, y}, i+1};
	}
	sort(P, P+N, [](const ppi &a, const ppi &b) {
		if((a.Fi < pii(0, 0)) != (b.Fi < pii(0, 0))) return a.Fi < b.Fi;
		return a.Fi / b.Fi > 0;
	});
	auto nxt = [](int i) { return i == N-1 ? 0 : i+1; };
	auto prv = [](int i) { return i == 0 ? N-1 : i-1; };
	rep(i, N) {
		vector <int> cvx = {i};
		for(int j=nxt(i);j!=i;j=nxt(j)) {
			if(P[i].Fi / P[j].Fi < 0) break;
			while(szz(cvx) > 1 && (P[cvx.back()].Fi - P[cvx[szz(cvx)-2]].Fi) / (P[j].Fi - P[cvx.back()].Fi) >= 0) cvx.pop_back();
			FL v = D[i][cvx.back()] + dist(P[j].Fi - P[cvx.back()].Fi);
			D[i][j] = D[j][i] = v;
			cvx.pb(j);
		}
	}
	rep(i, N) fv[i][i] = i;
	for(int l=1;l<N;l++) {
		rep(i, N) {
			int j = (i + l) % N;
			for(int k=fv[i][prv(j)];;k=nxt(k)) {
				if(F[i][j] < D[i][k] + D[k][j]) {
					F[i][j] = D[i][k] + D[k][j];
					fv[i][j] = k;
				}
				if(k == fv[nxt(i)][j]) break;
			}
		}
	}
	rep(i, N) {
		int pi = P[i].Se;
		rep(j, N) S[pi][pi] = max(S[pi][pi], D[i][j] * 2);
		rep(j, i) {
			int pj = P[j].Se;
			S[pj][pi] = S[pi][pj] = max(F[i][j], F[j][i]);
		}
	}
	for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) S[i][j] += S[i-1][j] + S[i][j-1] - S[i-1][j-1];
	int q; scanf("%d", &q);
	rep(qq, q) {
		int a, b, c, d;
		scanf("%d%d%d%d", &a, &b, &c, &d);
		FL v = S[b][d] - S[a-1][d] - S[b][c-1] + S[a-1][c-1];
		int cnt = (b-a+1) * (d-c+1);
		printf("%.12Lf\n", v / cnt);
	}
	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 210480
final_rank: 4