Problem:
Score : 1300 points

Problem Statement

You are playing a game and your goal is to maximize your expected gain.
At the beginning of the game, a pawn is put, uniformly at random, at a position p\in\{1,2,\dots, N\}. The N positions are arranged on a circle (so that 1 is between N and 2).

The game consists of turns. At each turn you can either end the game, and get A_p dollars (where p is the current position of the pawn), or pay B_p dollar to keep playing.
If you decide to keep playing, the pawn is randomly moved to one of the two adjacent positions p-1, p+1 (with the identifications 0 = N and N+1=1).

What is the expected gain of an optimal strategy?

Note: The "expected gain of an optimal strategy" shall be defined as the supremum of the expected gain among all strategies such that the game ends in a finite number of turns.

Constraints

2 \le N \le 200,000

0 \le A_p \le 10^{12} for any p = 1,\ldots, N

0 \le B_p \le 100 for any p = 1, \ldots, N

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 \cdots A_N
B_1 B_2 \cdots B_N

Output

Print a single real number, the expected gain of an optimal strategy.
Your answer will be considered correct if its relative or absolute error does not exceed 10^{-10}.

Sample Input 1

5
4 2 6 3 5
1 1 1 1 1

Sample Output 1

4.700000000000

Sample Input 2

4
100 0 100 0
0 100 0 100

Sample Output 2

50.000000000000

Sample Input 3

14
4839 5400 6231 5800 6001 5200 6350 7133 7986 8012 7537 7013 6477 5912
34 54 61 32 52 61 21 43 65 12 45 21 1 4

Sample Output 3

7047.142857142857

Sample Input 4

10
470606482521 533212137322 116718867454 746976621474 457112271419 815899162072 641324977314 88281100571 9231169966 455007126951
26 83 30 59 100 88 84 91 54 61

Sample Output 4

815899161079.400024414062

Solution in Java (OpenJDK 11.0.6) (judge verdict: Time Limit Exceeded)

import java.io.*;
import java.util.*;

public class Main {
    FastScanner in;
    PrintWriter out;

    long[] a;
    int[] b;
    int n;

    int f(int pos) {
        return pos % n;
    }

    double calc(int from, int dist, double curAv) {
        if (dist <= 1) {
            return 0.0;
        }
        double sumB = 0;
        for (int i = 1; i < dist; i++) {
            sumB += b[f(from + i)];
        }
        curAv -= sumB;
        double res = calc(from + 1, dist - 2, curAv);
        if (dist == 2) {
            return res + curAv;
        } else {
            return res + curAv * 2;
        }
    }

    long solveDp() {
        long[] dp = new long[n + 1];
        dp[0] = 0;
        for (int lastPos = 0; lastPos < n; lastPos++) {
            long sumB = 0;
            for (int nextPos = lastPos + 1; nextPos <= n; nextPos++) {
                long ncost = dp[lastPos] + a[nextPos] * 2;
                long avCost = a[lastPos] + a[nextPos];
                long curBsum = sumB;
                long totAdditionalCost = sumB;
                for (int from = lastPos + 1, to = nextPos -1; from <= to; from++,to--) {
                    long more = avCost - totAdditionalCost * 2;
                    if (from == to) {
                        ncost += more;
                    } else {
                        ncost += more * 2;
                    }
                    curBsum -= b[from];
                    curBsum -= b[to];
                    totAdditionalCost += curBsum;
                }
                dp[nextPos] = Math.max(dp[nextPos], ncost);
                sumB += b[nextPos];
            }
        }
        return dp[n];
    }

    void solve() {
        n = in.nextInt();
        a = new long[n];
        b = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.nextLong();
        }
        for (int i = 0; i < n; i++) {
            b[i] = in.nextInt();
        }
        int maxPos = 0;
        for (int i = 0; i < n; i++) {
            if (a[i] > a[maxPos]) {
                maxPos = i;
            }
        }
        long[] na = new long[n + 1];
        int[] nb = new int[n + 1];
        for (int i = 0; i < n; i++) {
            na[i] = a[f(i + maxPos)];
            nb[i] = b[f(i + maxPos)];
        }
        na[n] = na[0];
        nb[n] = nb[0];
        a = na;
        b = nb;
        out.println(solveDp() / 2.0 / n);
    }

    void solve22() {
        n = in.nextInt();
        a = new long[n];
        b = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.nextLong();
        }
        for (int i = 0; i < n; i++) {
            b[i] = in.nextInt();
        }
        double bestAns = 0;
        for (int mask = 1; mask < 1 << n; mask++) {
            double curAns = 0;
            List<Integer> pos = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                if (((1 << i) & mask) != 0) {
                    curAns += a[i];
                    pos.add(i);
                }
            }
            for (int i = 0; i < pos.size(); i++) {
                int from = pos.get(i), to = pos.get((i + 1) % pos.size());
                int dist = (to - from + n) % n;
                if (dist == 0) {
                    dist += n;
                }
                curAns += calc(from, dist, (a[from] + a[to]) / 2.0);
            }
            curAns /= n;
            bestAns = Math.max(bestAns, curAns);
        }
        out.println(bestAns);
    }


    final int mod = 988244353;

    int mul(int x, int y) {
        return (int) ((x * 1L * y) % mod);
    }

    void run() {
        try {
            in = new FastScanner(new File("Main.in"));
            out = new PrintWriter(new File("Main.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    void runIO() {

        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();
        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        public FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }

    public static void main(String[] args) {
        new Main().runIO();
    }
}