Problem:
F - Point Distance
Problem Statement
You work for invention center as a part time programmer. This center researches movement of protein molecules. It needs how molecules make clusters, so it will calculate distance of all pair molecules and will make a histogram.
Molecules’ positions are given by a
N
x
N
grid map.
Value
C_{xy}
of cell
(x, y)
in a grid map means that
C_{xy}
molecules are in the position
(x, y)
.
You are given a grid map, please calculate histogram of all pair molecules.
Input
Input is formatted as follows.
N
C_{11}
C_{12}
...
C_{1N}
C_{21}
C_{22}
...
C_{2N}
...
C_{N1}
C_{N2}
...
C_{NN}
First line contains the grid map size
N
(
1 \leq N \leq 1024
).
Each next
N
line contains
N
numbers.
Each numbers
C_{xy}
(
0 \leq C_{xy} \leq 9
) means the number of molecule in position (x,y).
There are at least 2 molecules.
Output
Output is formatted as follows.
D_{ave}
d_{1}
c_{1}
d_{2}
c_{2}
...
d_{m}
c_{m}
Print
D_{ave}
which an average distance of all pair molecules on first line.
Next, print histogram of all pair distance.
Each line contains a distance
d_i
and the number of pair molecules
c_i(0 \lt c_i)
.
The distance
d_i
should be calculated by squared Euclidean distance and sorted as increasing order.
If the number of different distance is more than 10,000, please show the first 10,000 lines.
The answer may be printed with an arbitrary number of decimal digits, but may not contain an absolute or relative error greater than or equal to
10^{-8}
.
Sample Input 1
2
1 0
0 1
Output for the Sample Input 1
1.4142135624
2 1
Sample Input 2
3
1 1 1
1 1 1
1 1 1
Output for the Sample Input 2
1.6349751825
1 12
2 8
4 6
5 8
8 2
Sample Input 3
5
0 1 2 3 4
5 6 7 8 9
1 2 3 2 1
0 0 0 0 0
0 0 0 0 1
Output for the Sample Input 3
1.8589994382
0 125
1 379
2 232
4 186
5 200
8 27
9 111
10 98
13 21
16 50
17 37
18 6
20 7
25 6

Submitted solutions:

code_snippet: //sagitta
#include <bits/stdc++.h>
using namespace std;
const int N=1<<23,M=1<<10;
const double pi=acos(-1);
typedef complex <double> E;
int mp[M][M];
int n,m,L;
int R[N];
long long cnt[N];
E a[N],b[N];
int sum;
double ans;
void fft(E *A,int f)
{
	for(int i=0;i<n;++i)
		if(i<R[i])
			swap(A[i],A[R[i]]);
	for(int i=1;i<n;i<<=1)
	{
		E wn(cos(pi/i),sin(pi/i)*f);
		for(int p=i<<1,j=0;j<n;j+=p)
		{
			E w(1,0);
			for(int k=0;k<i;++k,w*=wn)
			{
				E x=A[j+k],y=w*A[j+k+i];
				A[j+k]=x+y;
				A[j+k+i]=x-y;
			}
		}
	}
}
int getdist(int x,int y)
{
	return x*x+y*y;
}
int main()
{
	scanf("%d",&m);
	for(n=1;n<m*2;n<<=1)
		++L;
	for(int i=0;i<m;++i)
		for(int j=0;j<m;++j)
		{
			scanf("%d",&mp[i][j]);
			sum+=mp[i][j];
			cnt[0]-=mp[i][j];
			a[i*n+j]=mp[i][j];
			b[(n-i-1)*n+(n-j-1)]=mp[i][j];
		}
	n=n*n*2;
	L=L*2+1;
	for(int i=0;i<n;++i)
		R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
	fft(a,1);
	fft(b,1);
	for(int i=0;i<n;++i)
		a[i]*=b[i];
	fft(a,-1);
	int tn=sqrt(n/2)/2,x,y;
	x=tn;
	y=tn;
	for(int i=4*tn*tn-2*tn-1;i;--i)
	{
		int tmp1;
		if(y>=tn)
			tmp1=getdist(x-(tn*2-1),y-(tn*2-1));
		else
			tmp1=getdist(x-1-(tn*2-1),tn*2-1-(tn*2-1-y-1));
		double tmp2=a[x*tn*2+y].real()/n;
		ans+=sqrt(tmp1)*tmp2;
		cnt[tmp1]+=tmp2+0.5;
		x+=(y==tn*2-1);
		y=(y==tn*2-1?0:y+1);
	}
	printf("%.10f\n",ans/((long long)sum*(sum-1)));
	int flag=0;
	for(int i=0;i<m*m*2;++i)
		if(cnt[i])
		{
			printf("%d %lld\n",i,cnt[i]/2);
			if(++flag>=10000)
				break;
		}
	return 0;
}
accuracy: 1
time_ms: 2310
memory_kb: 319192
final_rank: 11

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

#define rep(i, n) for (int i = 0; i < (n); i++)
#define per(i, n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = (l); i < (r); i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define each(e, x) for (auto &e : x)
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define eb emplace_back
#define MM << ' ' <<
#define TT template <typename T>
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; }
TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; }

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << '\n';
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

TT int lb(vector<T> &v, T x) { return lower_bound(all(v), x) - begin(v); }
TT int ub(vector<T> &v, T x) { return upper_bound(all(v), x) - begin(v); }

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

using ld = long double;
using comp = complex<ld>;

struct FFT {
    const ld pi = acos(-1.0);
    vector<comp> r, ir;

    FFT() {
        r.resize(30), ir.resize(30);
        rep(i, 30) {
            r[i] = -polar(ld(1), pi / (1 << (i + 1)));
            ir[i] = -polar(ld(1), -pi / (1 << (i + 1)));
        }
    }

    vector<comp> to_comp(vector<ll> a) {
        int n = sz(a);
        vector<comp> b(n);
        rep(i, n) b[i] = comp(a[i], 0);
        return b;
    }

    vector<ll> to_ll(vector<comp> a) {
        int n = sz(a);
        vector<ll> b(n);
        rep(i, n) b[i] = round(a[i].real());
        return b;
    }

    void fft(vector<comp> &a) {
        int n = sz(a);
        for (int k = n; k >>= 1;) {
            comp w = 1;
            for (int s = 0, t = 0; s < n; s += 2 * k) {
                for (int i = s, j = s + k; i < s + k; i++, j++) {
                    comp x = a[i], y = w * a[j];
                    a[i] = x + y, a[j] = x - y;
                }
                w *= r[__builtin_ctz(++t)];
            }
        }
    }

    void ifft(vector<comp> &a) {
        int n = sz(a);
        for (int k = 1; k < n; k <<= 1) {
            comp w = 1;
            for (int s = 0, t = 0; s < n; s += 2 * k) {
                for (int i = s, j = s + k; i < s + k; i++, j++) {
                    comp x = a[i], y = a[j];
                    a[i] = x + y, a[j] = w * (x - y);
                }
                w *= ir[__builtin_ctz(++t)];
            }
        }
        rep(i, n) a[i] /= n;
    }

    vector<ll> convolve(vector<ll> a, vector<ll> b) {
        if (empty(a) || empty(b)) return {};
        int k = sz(a) + sz(b) - 1, n = 1;
        while (n < k) n <<= 1;
        a.resize(n), b.resize(n);
        vector<comp> A = to_comp(a), B = to_comp(b);
        fft(A), fft(B);
        rep(i, n) A[i] *= B[i];
        ifft(A);
        a = to_ll(A);
        a.resize(k);
        return a;
    }
};

FFT fft;
const int n = 1 << 11;

vector<vector<comp>> fft_2D(vector<vector<ll>> a) {
    a.resize(n);
    rep(i, n) a[i].resize(n, 0);
    vector<vector<comp>> ret(n);
    rep(i, n) ret[i] = fft.to_comp(a[i]);
    rep(i, n) fft.fft(ret[i]);
    rep(j, n) {
        vector<comp> tmp(n);
        rep(i, n) tmp[i] = ret[i][j];
        fft.fft(tmp);
        rep(i, n) ret[i][j] = tmp[i];
    }
    return ret;
}

vector<vector<ll>> ifft_2D(vector<vector<comp>> a) {
    rep(j, n) {
        vector<comp> tmp(n);
        rep(i, n) tmp[i] = a[i][j];
        fft.ifft(tmp);
        rep(i, n) a[i][j] = tmp[i];
    }
    rep(i, n) fft.ifft(a[i]);
    vector<vector<ll>> ret(n);
    rep(i, n) ret[i] = fft.to_ll(a[i]);
    return ret;
}

vector<vector<ll>> convolve_2D(vector<vector<ll>> a, vector<vector<ll>> b) {
    auto A = fft_2D(a), B = fft_2D(b);
    rep(i, n) rep(j, n) A[i][j] *= B[i][j];
    return ifft_2D(A);
}

int main() {
    int N;
    cin >> N;

    vector<vector<ll>> c(N, vector<ll>(N));
    rep(i, N) rep(j, N) cin >> c[i][j];

    auto c2 = c;
    reverse(all(c2));
    each(v, c2) reverse(all(v));

    auto a = convolve_2D(c, c2);

    int M = (N - 1) * (N - 1) * 2;
    vector<ll> cnt(M + 1, 0);

    rep2(i, -N + 1, N) rep2(j, -N + 1, N) {
        cnt[i * i + j * j] += a[N - 1 + i][N - 1 + j]; //
    }

    rep(i, N) rep(j, N) cnt[0] -= c[i][j];
    each(e, cnt) e >>= 1;

    ld sum = 0;
    rep(i, M + 1) sum += sqrt(i) * cnt[i];
    cout << sum / accumulate(all(cnt), 0LL) << '\n';

    vector<pll> ans;
    rep(i, M + 1) {
        if (cnt[i] == 0) continue;
        if (sz(ans) < 10000) ans.eb(i, cnt[i]);
    }

    each(e, ans) cout << e.first MM e.second << '\n';
}
accuracy: 1
time_ms: 3520
memory_kb: 462904
final_rank: 12

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

#define rep(i, n) for (int i = 0; i < (n); i++)
#define per(i, n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = (l); i < (r); i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define each(e, x) for (auto &e : x)
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define eb emplace_back
#define MM << ' ' <<
#define TT template <typename T>
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; }
TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; }

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << '\n';
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

TT int lb(vector<T> &v, T x) { return lower_bound(all(v), x) - begin(v); }
TT int ub(vector<T> &v, T x) { return upper_bound(all(v), x) - begin(v); }

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

using ld = long double;
using comp = complex<ld>;

struct FFT {
    const ld pi = acos(-1.0);
    vector<comp> r, ir;

    FFT() {
        r.resize(30), ir.resize(30);
        rep(i, 30) {
            r[i] = -polar(ld(1), pi / (1 << (i + 1)));
            ir[i] = -polar(ld(1), -pi / (1 << (i + 1)));
        }
    }

    vector<comp> to_comp(vector<ll> a) {
        int n = sz(a);
        vector<comp> b(n);
        rep(i, n) b[i] = comp(a[i], 0);
        return b;
    }

    vector<ll> to_ll(vector<comp> a) {
        int n = sz(a);
        vector<ll> b(n);
        rep(i, n) b[i] = a[i].real() + 0.1;
        return b;
    }

    void fft(vector<comp> &a) {
        int n = sz(a);
        for (int k = n; k >>= 1;) {
            comp w = 1;
            for (int s = 0, t = 0; s < n; s += 2 * k) {
                for (int i = s, j = s + k; i < s + k; i++, j++) {
                    comp x = a[i], y = w * a[j];
                    a[i] = x + y, a[j] = x - y;
                }
                w *= r[__builtin_ctz(++t)];
            }
        }
    }

    void ifft(vector<comp> &a) {
        int n = sz(a);
        for (int k = 1; k < n; k <<= 1) {
            comp w = 1;
            for (int s = 0, t = 0; s < n; s += 2 * k) {
                for (int i = s, j = s + k; i < s + k; i++, j++) {
                    comp x = a[i], y = a[j];
                    a[i] = x + y, a[j] = w * (x - y);
                }
                w *= ir[__builtin_ctz(++t)];
            }
        }
        rep(i, n) a[i] /= n;
    }

    vector<ll> convolve(vector<ll> a, vector<ll> b) {
        if (empty(a) || empty(b)) return {};
        int k = sz(a) + sz(b) - 1, n = 1;
        while (n < k) n <<= 1;
        a.resize(n), b.resize(n);
        vector<comp> A = to_comp(a), B = to_comp(b);
        fft(A), fft(B);
        rep(i, n) A[i] *= B[i];
        ifft(A);
        a = to_ll(A);
        a.resize(k);
        return a;
    }
};

FFT fft;
const int n = 1 << 11;

vector<vector<comp>> fft_2D(vector<vector<ll>> a) {
    a.resize(n);
    rep(i, n) a[i].resize(n, 0);
    vector<vector<comp>> ret(n);
    rep(i, n) ret[i] = fft.to_comp(a[i]);
    rep(i, n) fft.fft(ret[i]);
    rep(j, n) {
        vector<comp> tmp(n);
        rep(i, n) tmp[i] = ret[i][j];
        fft.fft(tmp);
        rep(i, n) ret[i][j] = tmp[i];
    }
    return ret;
}

vector<vector<ll>> ifft_2D(vector<vector<comp>> a) {
    rep(j, n) {
        vector<comp> tmp(n);
        rep(i, n) tmp[i] = a[i][j];
        fft.ifft(tmp);
        rep(i, n) a[i][j] = tmp[i];
    }
    rep(i, n) fft.ifft(a[i]);
    vector<vector<ll>> ret(n);
    rep(i, n) ret[i] = fft.to_ll(a[i]);
    return ret;
}

vector<vector<ll>> convolve_2D(vector<vector<ll>> a, vector<vector<ll>> b) {
    auto A = fft_2D(a), B = fft_2D(b);
    rep(i, n) rep(j, n) A[i][j] *= B[i][j];
    return ifft_2D(A);
}

int main() {
    int N;
    cin >> N;

    vector<vector<ll>> c(N, vector<ll>(N));
    rep(i, N) rep(j, N) cin >> c[i][j];

    auto c2 = c;
    reverse(all(c2));
    each(v, c2) reverse(all(v));

    auto a = convolve_2D(c, c2);

    int M = (N - 1) * (N - 1) * 2;
    vector<ll> cnt(M + 1, 0);

    rep2(i, -N + 1, N) rep2(j, -N + 1, N) {
        cnt[i * i + j * j] += a[N - 1 + i][N - 1 + j]; //
    }

    rep(i, N) rep(j, N) cnt[0] -= c[i][j];
    each(e, cnt) e >>= 1;

    ld sum = 0;
    rep(i, M + 1) sum += sqrt(i) * cnt[i];
    cout << sum / accumulate(all(cnt), 0LL) << '\n';

    vector<pii> ans;
    rep(i, M + 1) {
        if (cnt[i] == 0) continue;
        if (sz(ans) < 10000) ans.eb(i, cnt[i]);
    }

    each(e, ans) cout << e.first MM e.second << '\n';
}
accuracy: 0.90625
time_ms: 3480
memory_kb: 462788
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=210005,INF=1<<28;

//modint+畳み込み+逆元テーブル

// from: https://gist.github.com/yosupo06/ddd51afb727600fd95d9d8ad6c3c80c9
// (based on AtCoder STL)

#include <algorithm>
#include <array>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {
    
    namespace internal {
        
        int ceil_pow2(int n) {
            int x = 0;
            while ((1U << x) < (unsigned int)(n)) x++;
            return x;
        }
        
        int bsf(unsigned int n) {
#ifdef _MSC_VER
            unsigned long index;
            _BitScanForward(&index, n);
            return index;
#else
            return __builtin_ctz(n);
#endif
        }
        
    }  // namespace internal
    
}  // namespace atcoder



#include <utility>

namespace atcoder {
    
    namespace internal {
        
        constexpr long long safe_mod(long long x, long long m) {
            x %= m;
            if (x < 0) x += m;
            return x;
        }
        
        struct barrett {
            unsigned int _m;
            unsigned long long im;
            
            barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}
            
            unsigned int umod() const { return _m; }
            
            unsigned int mul(unsigned int a, unsigned int b) const {
                
                unsigned long long z = a;
                z *= b;
#ifdef _MSC_VER
                unsigned long long x;
                _umul128(z, im, &x);
#else
                unsigned long long x =
                (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
                unsigned int v = (unsigned int)(z - x * _m);
                if (_m <= v) v += _m;
                return v;
            }
        };
        
        constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
            if (m == 1) return 0;
            unsigned int _m = (unsigned int)(m);
            unsigned long long r = 1;
            unsigned long long y = safe_mod(x, m);
            while (n) {
                if (n & 1) r = (r * y) % _m;
                y = (y * y) % _m;
                n >>= 1;
            }
            return r;
        }
        
        constexpr bool is_prime_constexpr(int n) {
            if (n <= 1) return false;
            if (n == 2 || n == 7 || n == 61) return true;
            if (n % 2 == 0) return false;
            long long d = n - 1;
            while (d % 2 == 0) d /= 2;
            for (long long a : {2, 7, 61}) {
                long long t = d;
                long long y = pow_mod_constexpr(a, t, n);
                while (t != n - 1 && y != 1 && y != n - 1) {
                    y = y * y % n;
                    t <<= 1;
                }
                if (y != n - 1 && t % 2 == 0) {
                    return false;
                }
            }
            return true;
        }
        template <int n> constexpr bool is_prime = is_prime_constexpr(n);
        
        constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
            a = safe_mod(a, b);
            if (a == 0) return {b, 0};
            
            long long s = b, t = a;
            long long m0 = 0, m1 = 1;
            
            while (t) {
                long long u = s / t;
                s -= t * u;
                m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b
                
                
                auto tmp = s;
                s = t;
                t = tmp;
                tmp = m0;
                m0 = m1;
                m1 = tmp;
            }
            if (m0 < 0) m0 += b / s;
            return {s, m0};
        }
        
        constexpr int primitive_root_constexpr(int m) {
            if (m == 2) return 1;
            if (m == 167772161) return 3;
            if (m == 469762049) return 3;
            if (m == 754974721) return 11;
            if (m == 998244353) return 3;
            int divs[20] = {};
            divs[0] = 2;
            int cnt = 1;
            int x = (m - 1) / 2;
            while (x % 2 == 0) x /= 2;
            for (int i = 3; (long long)(i)*i <= x; i += 2) {
                if (x % i == 0) {
                    divs[cnt++] = i;
                    while (x % i == 0) {
                        x /= i;
                    }
                }
            }
            if (x > 1) {
                divs[cnt++] = x;
            }
            for (int g = 2;; g++) {
                bool ok = true;
                for (int i = 0; i < cnt; i++) {
                    if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                        ok = false;
                        break;
                    }
                }
                if (ok) return g;
            }
        }
        template <int m> constexpr int primitive_root = primitive_root_constexpr(m);
        
    }  // namespace internal
    
}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {
    
    namespace internal {
        
#ifndef _MSC_VER
        template <class T>
        using is_signed_int128 =
        typename std::conditional<std::is_same<T, __int128_t>::value ||
        std::is_same<T, __int128>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_unsigned_int128 =
        typename std::conditional<std::is_same<T, __uint128_t>::value ||
        std::is_same<T, unsigned __int128>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using make_unsigned_int128 =
        typename std::conditional<std::is_same<T, __int128_t>::value,
        __uint128_t,
        unsigned __int128>;
        
        template <class T>
        using is_integral = typename std::conditional<std::is_integral<T>::value ||
        is_signed_int128<T>::value ||
        is_unsigned_int128<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                         std::is_signed<T>::value) ||
        is_signed_int128<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_unsigned_int =
        typename std::conditional<(is_integral<T>::value &&
                                   std::is_unsigned<T>::value) ||
        is_unsigned_int128<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using to_unsigned = typename std::conditional<
        is_signed_int128<T>::value,
        make_unsigned_int128<T>,
        typename std::conditional<std::is_signed<T>::value,
        std::make_unsigned<T>,
        std::common_type<T>>::type>::type;
        
#else
        
        template <class T> using is_integral = typename std::is_integral<T>;
        
        template <class T>
        using is_signed_int =
        typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_unsigned_int =
        typename std::conditional<is_integral<T>::value &&
        std::is_unsigned<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using to_unsigned = typename std::conditional<is_signed_int<T>::value,
        std::make_unsigned<T>,
        std::common_type<T>>::type;
        
#endif
        
        template <class T>
        using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;
        
        template <class T>
        using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;
        
        template <class T> using to_unsigned_t = typename to_unsigned<T>::type;
        
    }  // namespace internal
    
}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {
    
    namespace internal {
        
        struct modint_base {};
        struct static_modint_base : modint_base {};
        
        template <class T> using is_modint = std::is_base_of<modint_base, T>;
        template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;
        
    }  // namespace internal
    
    template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
    struct static_modint : internal::static_modint_base {
        using mint = static_modint;
        
    public:
        static constexpr int mod() { return m; }
        static mint raw(int v) {
            mint x;
            x._v = v;
            return x;
        }
        
        static_modint() : _v(0) {}
        template <class T, internal::is_signed_int_t<T>* = nullptr>
        static_modint(T v) {
            long long x = (long long)(v % (long long)(umod()));
            if (x < 0) x += umod();
            _v = (unsigned int)(x);
        }
        template <class T, internal::is_unsigned_int_t<T>* = nullptr>
        static_modint(T v) {
            _v = (unsigned int)(v % umod());
        }
        static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }
        
        unsigned int val() const { return _v; }
        
        mint& operator++() {
            _v++;
            if (_v == umod()) _v = 0;
            return *this;
        }
        mint& operator--() {
            if (_v == 0) _v = umod();
            _v--;
            return *this;
        }
        mint operator++(int) {
            mint result = *this;
            ++*this;
            return result;
        }
        mint operator--(int) {
            mint result = *this;
            --*this;
            return result;
        }
        
        mint& operator+=(const mint& rhs) {
            _v += rhs._v;
            if (_v >= umod()) _v -= umod();
            return *this;
        }
        mint& operator-=(const mint& rhs) {
            _v -= rhs._v;
            if (_v >= umod()) _v += umod();
            return *this;
        }
        mint& operator*=(const mint& rhs) {
            unsigned long long z = _v;
            z *= rhs._v;
            _v = (unsigned int)(z % umod());
            return *this;
        }
        mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
        
        mint operator+() const { return *this; }
        mint operator-() const { return mint() - *this; }
        
        mint pow(long long n) const {
            assert(0 <= n);
            mint x = *this, r = 1;
            while (n) {
                if (n & 1) r *= x;
                x *= x;
                n >>= 1;
            }
            return r;
        }
        mint inv() const {
            if (prime) {
                assert(_v);
                return pow(umod() - 2);
            } else {
                auto eg = internal::inv_gcd(_v, m);
                assert(eg.first == 1);
                return eg.second;
            }
        }
        
        friend mint operator+(const mint& lhs, const mint& rhs) {
            return mint(lhs) += rhs;
        }
        friend mint operator-(const mint& lhs, const mint& rhs) {
            return mint(lhs) -= rhs;
        }
        friend mint operator*(const mint& lhs, const mint& rhs) {
            return mint(lhs) *= rhs;
        }
        friend mint operator/(const mint& lhs, const mint& rhs) {
            return mint(lhs) /= rhs;
        }
        friend bool operator==(const mint& lhs, const mint& rhs) {
            return lhs._v == rhs._v;
        }
        friend bool operator!=(const mint& lhs, const mint& rhs) {
            return lhs._v != rhs._v;
        }
        
    private:
        unsigned int _v;
        static constexpr unsigned int umod() { return m; }
        static constexpr bool prime = internal::is_prime<m>;
    };
    
    template <int id> struct dynamic_modint : internal::modint_base {
        using mint = dynamic_modint;
        
    public:
        static int mod() { return (int)(bt.umod()); }
        static void set_mod(int m) {
            assert(1 <= m);
            bt = internal::barrett(m);
        }
        static mint raw(int v) {
            mint x;
            x._v = v;
            return x;
        }
        
        dynamic_modint() : _v(0) {}
        template <class T, internal::is_signed_int_t<T>* = nullptr>
        dynamic_modint(T v) {
            long long x = (long long)(v % (long long)(mod()));
            if (x < 0) x += mod();
            _v = (unsigned int)(x);
        }
        template <class T, internal::is_unsigned_int_t<T>* = nullptr>
        dynamic_modint(T v) {
            _v = (unsigned int)(v % mod());
        }
        dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }
        
        unsigned int val() const { return _v; }
        
        mint& operator++() {
            _v++;
            if (_v == umod()) _v = 0;
            return *this;
        }
        mint& operator--() {
            if (_v == 0) _v = umod();
            _v--;
            return *this;
        }
        mint operator++(int) {
            mint result = *this;
            ++*this;
            return result;
        }
        mint operator--(int) {
            mint result = *this;
            --*this;
            return result;
        }
        
        mint& operator+=(const mint& rhs) {
            _v += rhs._v;
            if (_v >= umod()) _v -= umod();
            return *this;
        }
        mint& operator-=(const mint& rhs) {
            _v += mod() - rhs._v;
            if (_v >= umod()) _v -= umod();
            return *this;
        }
        mint& operator*=(const mint& rhs) {
            _v = bt.mul(_v, rhs._v);
            return *this;
        }
        mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
        
        mint operator+() const { return *this; }
        mint operator-() const { return mint() - *this; }
        
        mint pow(long long n) const {
            assert(0 <= n);
            mint x = *this, r = 1;
            while (n) {
                if (n & 1) r *= x;
                x *= x;
                n >>= 1;
            }
            return r;
        }
        mint inv() const {
            auto eg = internal::inv_gcd(_v, mod());
            assert(eg.first == 1);
            return eg.second;
        }
        
        friend mint operator+(const mint& lhs, const mint& rhs) {
            return mint(lhs) += rhs;
        }
        friend mint operator-(const mint& lhs, const mint& rhs) {
            return mint(lhs) -= rhs;
        }
        friend mint operator*(const mint& lhs, const mint& rhs) {
            return mint(lhs) *= rhs;
        }
        friend mint operator/(const mint& lhs, const mint& rhs) {
            return mint(lhs) /= rhs;
        }
        friend bool operator==(const mint& lhs, const mint& rhs) {
            return lhs._v == rhs._v;
        }
        friend bool operator!=(const mint& lhs, const mint& rhs) {
            return lhs._v != rhs._v;
        }
        
    private:
        unsigned int _v;
        static internal::barrett bt;
        static unsigned int umod() { return bt.umod(); }
    };
    template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;
    
    using modint998244353 = static_modint<998244353>;
    using modint1000000007 = static_modint<1000000007>;
    using modint = dynamic_modint<-1>;
    
    namespace internal {
        
        template <class T>
        using is_static_modint = std::is_base_of<internal::static_modint_base, T>;
        
        template <class T>
        using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;
        
        template <class> struct is_dynamic_modint : public std::false_type {};
        template <int id>
        struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};
        
        template <class T>
        using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;
        
    }  // namespace internal
    
}  // namespace atcoder

#include <cassert>
#include <type_traits>
#include <vector>

namespace atcoder {
    
    namespace internal {
        
        template <class mint, internal::is_static_modint_t<mint>* = nullptr>
        void butterfly(std::vector<mint>& a) {
            static constexpr int g = internal::primitive_root<mint::mod()>;
            int n = int(a.size());
            int h = internal::ceil_pow2(n);
            
            static bool first = true;
            static mint sum_e[30];  // sum_e[i] = ies[0] * ... * ies[i - 1] * es[i]
            if (first) {
                first = false;
                mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
                int cnt2 = bsf(mint::mod() - 1);
                mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
                for (int i = cnt2; i >= 2; i--) {
                    es[i - 2] = e;
                    ies[i - 2] = ie;
                    e *= e;
                    ie *= ie;
                }
                mint now = 1;
                for (int i = 0; i < cnt2 - 2; i++) {
                    sum_e[i] = es[i] * now;
                    now *= ies[i];
                }
            }
            for (int ph = 1; ph <= h; ph++) {
                int w = 1 << (ph - 1), p = 1 << (h - ph);
                mint now = 1;
                for (int s = 0; s < w; s++) {
                    int offset = s << (h - ph + 1);
                    for (int i = 0; i < p; i++) {
                        auto l = a[i + offset];
                        auto r = a[i + offset + p] * now;
                        a[i + offset] = l + r;
                        a[i + offset + p] = l - r;
                    }
                    now *= sum_e[bsf(~(unsigned int)(s))];
                }
            }
        }
        
        template <class mint, internal::is_static_modint_t<mint>* = nullptr>
        void butterfly_inv(std::vector<mint>& a) {
            static constexpr int g = internal::primitive_root<mint::mod()>;
            int n = int(a.size());
            int h = internal::ceil_pow2(n);
            
            static bool first = true;
            static mint sum_ie[30];  // sum_ie[i] = es[0] * ... * es[i - 1] * ies[i]
            if (first) {
                first = false;
                mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
                int cnt2 = bsf(mint::mod() - 1);
                mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
                for (int i = cnt2; i >= 2; i--) {
                    es[i - 2] = e;
                    ies[i - 2] = ie;
                    e *= e;
                    ie *= ie;
                }
                mint now = 1;
                for (int i = 0; i < cnt2 - 2; i++) {
                    sum_ie[i] = ies[i] * now;
                    now *= es[i];
                }
            }
            
            for (int ph = h; ph >= 1; ph--) {
                int w = 1 << (ph - 1), p = 1 << (h - ph);
                mint inow = 1;
                for (int s = 0; s < w; s++) {
                    int offset = s << (h - ph + 1);
                    for (int i = 0; i < p; i++) {
                        auto l = a[i + offset];
                        auto r = a[i + offset + p];
                        a[i + offset] = l + r;
                        a[i + offset + p] =
                        (unsigned long long)(mint::mod() + l.val() - r.val()) *
                        inow.val();
                    }
                    inow *= sum_ie[bsf(~(unsigned int)(s))];
                }
            }
        }
        
    }  // namespace internal
    
    template <class mint, internal::is_static_modint_t<mint>* = nullptr>
    std::vector<mint> convolution(std::vector<mint> a, std::vector<mint> b) {
        int n = int(a.size()), m = int(b.size());
        if (!n || !m) return {};
        if (std::min(n, m) <= 60) {
            if (n < m) {
                std::swap(n, m);
                std::swap(a, b);
            }
            std::vector<mint> ans(n + m - 1);
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    ans[i + j] += a[i] * b[j];
                }
            }
            return ans;
        }
        int z = 1 << internal::ceil_pow2(n + m - 1);
        a.resize(z);
        internal::butterfly(a);
        b.resize(z);
        internal::butterfly(b);
        for (int i = 0; i < z; i++) {
            a[i] *= b[i];
        }
        internal::butterfly_inv(a);
        a.resize(n + m - 1);
        mint iz = mint(z).inv();
        for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
        return a;
    }
    
    template <unsigned int mod = 998244353,
    class T,
    std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
    std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
        int n = int(a.size()), m = int(b.size());
        if (!n || !m) return {};
        
        using mint = static_modint<mod>;
        std::vector<mint> a2(n), b2(m);
        for (int i = 0; i < n; i++) {
            a2[i] = mint(a[i]);
        }
        for (int i = 0; i < m; i++) {
            b2[i] = mint(b[i]);
        }
        auto c2 = convolution(move(a2), move(b2));
        std::vector<T> c(n + m - 1);
        for (int i = 0; i < n + m - 1; i++) {
            c[i] = c2[i].val();
        }
        return c;
    }
    
    std::vector<long long> convolution_ll(const std::vector<long long>& a,
                                          const std::vector<long long>& b) {
        int n = int(a.size()), m = int(b.size());
        if (!n || !m) return {};
        
        static constexpr unsigned long long MOD1 = 754974721;  // 2^24
        static constexpr unsigned long long MOD2 = 167772161;  // 2^25
        static constexpr unsigned long long MOD3 = 469762049;  // 2^26
        static constexpr unsigned long long M2M3 = MOD2 * MOD3;
        static constexpr unsigned long long M1M3 = MOD1 * MOD3;
        static constexpr unsigned long long M1M2 = MOD1 * MOD2;
        static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;
        
        static constexpr unsigned long long i1 =
        internal::inv_gcd(MOD2 * MOD3, MOD1).second;
        static constexpr unsigned long long i2 =
        internal::inv_gcd(MOD1 * MOD3, MOD2).second;
        static constexpr unsigned long long i3 =
        internal::inv_gcd(MOD1 * MOD2, MOD3).second;
        
        auto c1 = convolution<MOD1>(a, b);
        auto c2 = convolution<MOD2>(a, b);
        auto c3 = convolution<MOD3>(a, b);
        
        std::vector<long long> c(n + m - 1);
        for (int i = 0; i < n + m - 1; i++) {
            unsigned long long x = 0;
            x += (c1[i] * i1) % MOD1 * M2M3;
            x += (c2[i] * i2) % MOD2 * M1M3;
            x += (c3[i] * i3) % MOD3 * M1M2;
            long long diff =
            c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
            if (diff < 0) diff += MOD1;
            static constexpr unsigned long long offset[5] = {
                0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
            x -= offset[diff % 5];
            c[i] = x;
        }
        
        return c;
    }
    
}  // namespace atcoder

using mint=atcoder::modint998244353;

mint inv[MAX],fac[MAX],finv[MAX];

void make(){
    
    fac[0]=fac[1]=1;
    finv[0]=finv[1]=1;
    inv[1]=1;
    
    for(int i=2;i<MAX;i++){
        inv[i]=-inv[mod%i]*(mod/i);
        fac[i]=fac[i-1]*i;
        finv[i]=finv[i-1]*inv[i];
    }
}

mint comb(ll a,ll b){
    if(a<b) return 0;
    return fac[a]*finv[b]*finv[a-b];
}

mint perm(ll a,ll b){
    if(a<b) return 0;
    return fac[a]*finv[a-b];
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N;cin>>N;
    vector<vector<int>> S(N,vector<int>(N));
    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>S[i][j];
    
    vector<ll> A(2*N*N),B(2*N*N);
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            A[2*N*i+j]=S[i][j];
            B[2*N*(N-1-i)+(N-1-j)]=S[i][j];
        }
    }
    
    vector<ll> C=atcoder::convolution_ll(A,B);
    
    vector<ll> cn(2*N*N+3);
    
    for(int i=0;i<2*N*(N-1)+N-1;i++){
        ll x=i/(2*N),y=i%(2*N);
        if(C[i]==0) continue;
        x=abs(x-(N-1));
        y=abs(y-(N-1));
        cn[x*x+y*y]+=C[i];
    }
    
    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cn[0]+=S[i][j]*(S[i][j]-1)/2;
    
    double sum=0;
    ll pat=0;
    
    for(int i=0;i<si(cn);i++){
        sum+=sqrtl(i)*cn[i];
        pat+=cn[i];
    }
    
    cout<<fixed<<setprecision(25)<<(sum/pat)<<endl;
    int output=0;
    for(int i=0;i<si(cn);i++){
        if(cn[i]){
            cout<<i<<" "<<cn[i]<<"\n";
            output++;
            if(output==10000) return 0;
        }
    }
}
accuracy: 1
time_ms: 1040
memory_kb: 189728
final_rank: 5

code_snippet: #line 1 "a.cpp"
#include <bits/stdc++.h>

#line 1 "atcoder/convolution.hpp"



#line 7 "atcoder/convolution.hpp"
#include <type_traits>
#line 9 "atcoder/convolution.hpp"

#line 1 "atcoder/internal_bit.hpp"



#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder


#line 1 "atcoder/modint.hpp"



#line 7 "atcoder/modint.hpp"

#ifdef _MSC_VER
#include <intrin.h>
#endif

#line 1 "atcoder/internal_math.hpp"



#line 5 "atcoder/internal_math.hpp"

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m < 2^31`
    explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

// @param n `n < 2^32`
// @param m `1 <= m < 2^32`
// @return sum_{i=0}^{n-1} floor((ai + b) / m) (mod 2^64)
unsigned long long floor_sum_unsigned(unsigned long long n,
                                      unsigned long long m,
                                      unsigned long long a,
                                      unsigned long long b) {
    unsigned long long ans = 0;
    while (true) {
        if (a >= m) {
            ans += n * (n - 1) / 2 * (a / m);
            a %= m;
        }
        if (b >= m) {
            ans += n * (b / m);
            b %= m;
        }

        unsigned long long y_max = a * n + b;
        if (y_max < m) break;
        // y_max < m * (n + 1)
        // floor(y_max / m) <= n
        n = (unsigned long long)(y_max / m);
        b = (unsigned long long)(y_max % m);
        std::swap(m, a);
    }
    return ans;
}

}  // namespace internal

}  // namespace atcoder


#line 1 "atcoder/internal_type_traits.hpp"



#line 7 "atcoder/internal_type_traits.hpp"

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder


#line 14 "atcoder/modint.hpp"

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder


#line 12 "atcoder/convolution.hpp"

namespace atcoder {

namespace internal {

template <class mint,
          int g = internal::primitive_root<mint::mod()>,
          internal::is_static_modint_t<mint>* = nullptr>
struct fft_info {
    static constexpr int rank2 = bsf_constexpr(mint::mod() - 1);
    std::array<mint, rank2 + 1> root;   // root[i]^(2^i) == 1
    std::array<mint, rank2 + 1> iroot;  // root[i] * iroot[i] == 1

    std::array<mint, std::max(0, rank2 - 2 + 1)> rate2;
    std::array<mint, std::max(0, rank2 - 2 + 1)> irate2;

    std::array<mint, std::max(0, rank2 - 3 + 1)> rate3;
    std::array<mint, std::max(0, rank2 - 3 + 1)> irate3;

    fft_info() {
        root[rank2] = mint(g).pow((mint::mod() - 1) >> rank2);
        iroot[rank2] = root[rank2].inv();
        for (int i = rank2 - 1; i >= 0; i--) {
            root[i] = root[i + 1] * root[i + 1];
            iroot[i] = iroot[i + 1] * iroot[i + 1];
        }

        {
            mint prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 2; i++) {
                rate2[i] = root[i + 2] * prod;
                irate2[i] = iroot[i + 2] * iprod;
                prod *= iroot[i + 2];
                iprod *= root[i + 2];
            }
        }
        {
            mint prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 3; i++) {
                rate3[i] = root[i + 3] * prod;
                irate3[i] = iroot[i + 3] * iprod;
                prod *= iroot[i + 3];
                iprod *= root[i + 3];
            }
        }
    }
};

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static const fft_info<mint> info;

    int len = 0;  // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
    while (len < h) {
        if (h - len == 1) {
            int p = 1 << (h - len - 1);
            mint rot = 1;
            for (int s = 0; s < (1 << len); s++) {
                int offset = s << (h - len);
                for (int i = 0; i < p; i++) {
                    auto l = a[i + offset];
                    auto r = a[i + offset + p] * rot;
                    a[i + offset] = l + r;
                    a[i + offset + p] = l - r;
                }
                if (s + 1 != (1 << len))
                    rot *= info.rate2[bsf(~(unsigned int)(s))];
            }
            len++;
        } else {
            // 4-base
            int p = 1 << (h - len - 2);
            mint rot = 1, imag = info.root[2];
            for (int s = 0; s < (1 << len); s++) {
                mint rot2 = rot * rot;
                mint rot3 = rot2 * rot;
                int offset = s << (h - len);
                for (int i = 0; i < p; i++) {
                    auto mod2 = 1ULL * mint::mod() * mint::mod();
                    auto a0 = 1ULL * a[i + offset].val();
                    auto a1 = 1ULL * a[i + offset + p].val() * rot.val();
                    auto a2 = 1ULL * a[i + offset + 2 * p].val() * rot2.val();
                    auto a3 = 1ULL * a[i + offset + 3 * p].val() * rot3.val();
                    auto a1na3imag =
                        1ULL * mint(a1 + mod2 - a3).val() * imag.val();
                    auto na2 = mod2 - a2;
                    a[i + offset] = a0 + a2 + a1 + a3;
                    a[i + offset + 1 * p] = a0 + a2 + (2 * mod2 - (a1 + a3));
                    a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
                    a[i + offset + 3 * p] = a0 + na2 + (mod2 - a1na3imag);
                }
                if (s + 1 != (1 << len))
                    rot *= info.rate3[bsf(~(unsigned int)(s))];
            }
            len += 2;
        }
    }
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static const fft_info<mint> info;

    int len = h;  // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
    while (len) {
        if (len == 1) {
            int p = 1 << (h - len);
            mint irot = 1;
            for (int s = 0; s < (1 << (len - 1)); s++) {
                int offset = s << (h - len + 1);
                for (int i = 0; i < p; i++) {
                    auto l = a[i + offset];
                    auto r = a[i + offset + p];
                    a[i + offset] = l + r;
                    a[i + offset + p] =
                        (unsigned long long)(mint::mod() + l.val() - r.val()) *
                        irot.val();
                    ;
                }
                if (s + 1 != (1 << (len - 1)))
                    irot *= info.irate2[bsf(~(unsigned int)(s))];
            }
            len--;
        } else {
            // 4-base
            int p = 1 << (h - len);
            mint irot = 1, iimag = info.iroot[2];
            for (int s = 0; s < (1 << (len - 2)); s++) {
                mint irot2 = irot * irot;
                mint irot3 = irot2 * irot;
                int offset = s << (h - len + 2);
                for (int i = 0; i < p; i++) {
                    auto a0 = 1ULL * a[i + offset + 0 * p].val();
                    auto a1 = 1ULL * a[i + offset + 1 * p].val();
                    auto a2 = 1ULL * a[i + offset + 2 * p].val();
                    auto a3 = 1ULL * a[i + offset + 3 * p].val();

                    auto a2na3iimag =
                        1ULL *
                        mint((mint::mod() + a2 - a3) * iimag.val()).val();

                    a[i + offset] = a0 + a1 + a2 + a3;
                    a[i + offset + 1 * p] =
                        (a0 + (mint::mod() - a1) + a2na3iimag) * irot.val();
                    a[i + offset + 2 * p] =
                        (a0 + a1 + (mint::mod() - a2) + (mint::mod() - a3)) *
                        irot2.val();
                    a[i + offset + 3 * p] =
                        (a0 + (mint::mod() - a1) + (mint::mod() - a2na3iimag)) *
                        irot3.val();
                }
                if (s + 1 != (1 << (len - 2)))
                    irot *= info.irate3[bsf(~(unsigned int)(s))];
            }
            len -= 2;
        }
    }
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_naive(const std::vector<mint>& a,
                                    const std::vector<mint>& b) {
    int n = int(a.size()), m = int(b.size());
    std::vector<mint> ans(n + m - 1);
    if (n < m) {
        for (int j = 0; j < m; j++) {
            for (int i = 0; i < n; i++) {
                ans[i + j] += a[i] * b[j];
            }
        }
    } else {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans[i + j] += a[i] * b[j];
            }
        }
    }
    return ans;
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_fft(std::vector<mint> a, std::vector<mint> b) {
    int n = int(a.size()), m = int(b.size());
    int z = 1 << internal::ceil_pow2(n + m - 1);
    a.resize(z);
    internal::butterfly(a);
    b.resize(z);
    internal::butterfly(b);
    for (int i = 0; i < z; i++) {
        a[i] *= b[i];
    }
    internal::butterfly_inv(a);
    a.resize(n + m - 1);
    mint iz = mint(z).inv();
    for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
    return a;
}

}  // namespace internal

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint>&& a, std::vector<mint>&& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};
    if (std::min(n, m) <= 60) return convolution_naive(a, b);
    return internal::convolution_fft(a, b);
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(const std::vector<mint>& a,
                              const std::vector<mint>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};
    if (std::min(n, m) <= 60) return convolution_naive(a, b);
    return internal::convolution_fft(a, b);
}

template <unsigned int mod = 998244353,
          class T,
          std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    using mint = static_modint<mod>;
    std::vector<mint> a2(n), b2(m);
    for (int i = 0; i < n; i++) {
        a2[i] = mint(a[i]);
    }
    for (int i = 0; i < m; i++) {
        b2[i] = mint(b[i]);
    }
    auto c2 = convolution(move(a2), move(b2));
    std::vector<T> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        c[i] = c2[i].val();
    }
    return c;
}

std::vector<long long> convolution_ll(const std::vector<long long>& a,
                                      const std::vector<long long>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    static constexpr unsigned long long MOD1 = 754974721;  // 2^24
    static constexpr unsigned long long MOD2 = 167772161;  // 2^25
    static constexpr unsigned long long MOD3 = 469762049;  // 2^26
    static constexpr unsigned long long M2M3 = MOD2 * MOD3;
    static constexpr unsigned long long M1M3 = MOD1 * MOD3;
    static constexpr unsigned long long M1M2 = MOD1 * MOD2;
    static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;

    static constexpr unsigned long long i1 =
        internal::inv_gcd(MOD2 * MOD3, MOD1).second;
    static constexpr unsigned long long i2 =
        internal::inv_gcd(MOD1 * MOD3, MOD2).second;
    static constexpr unsigned long long i3 =
        internal::inv_gcd(MOD1 * MOD2, MOD3).second;

    auto c1 = convolution<MOD1>(a, b);
    auto c2 = convolution<MOD2>(a, b);
    auto c3 = convolution<MOD3>(a, b);

    std::vector<long long> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        unsigned long long x = 0;
        x += (c1[i] * i1) % MOD1 * M2M3;
        x += (c2[i] * i2) % MOD2 * M1M3;
        x += (c3[i] * i3) % MOD3 * M1M2;
        // B = 2^63, -B <= x, r(real value) < B
        // (x, x - M, x - 2M, or x - 3M) = r (mod 2B)
        // r = c1[i] (mod MOD1)
        // focus on MOD1
        // r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)
        // r = x,
        //     x - M' + (0 or 2B),
        //     x - 2M' + (0, 2B or 4B),
        //     x - 3M' + (0, 2B, 4B or 6B) (without mod!)
        // (r - x) = 0, (0)
        //           - M' + (0 or 2B), (1)
        //           -2M' + (0 or 2B or 4B), (2)
        //           -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)
        // we checked that
        //   ((1) mod MOD1) mod 5 = 2
        //   ((2) mod MOD1) mod 5 = 3
        //   ((3) mod MOD1) mod 5 = 4
        long long diff =
            c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
        if (diff < 0) diff += MOD1;
        static constexpr unsigned long long offset[5] = {
            0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
        x -= offset[diff % 5];
        c[i] = x;
    }

    return c;
}

}  // namespace atcoder


#line 4 "a.cpp"
using namespace std;
using ll = long long;
#define rep(i, n) for(int i = 0; i < n; i++)
using ld = long double;

int main() {
	int n;
	cin >> n;
	const int n2 = n + n;
	vector<ll> data(n2 * n);
	ld sum = 0.;
	ll pair_count = 0;
	map<int, ll> ans;
	rep(i, n) rep(j, n) {
		ll a;
		cin >> a;
		data[i * n2 + j] = a;
		if(a > 1) {
			const ll add_pr = a * (a - 1) / 2;
			ans[0] += add_pr;
			pair_count += add_pr;
		}
	}
	vector<ll> rev = data;
	reverse(begin(rev), end(rev));
	vector<ll> res = atcoder::convolution_ll(data, rev);

	for(int diff = 1; diff < n * n2; diff++) {
		int diff_row = diff / n2;
		int diff_col = diff % n2;
		if(diff_col == n) continue;
		if(diff_col > n) {
			diff_row++;
			diff_col -= n2;
		}
		const int dist_sq = diff_row * diff_row + diff_col * diff_col;
		ll ps = res[n * n2 - 1 - diff];

		if(ps) {
			ans[dist_sq] += ps;
			sum += sqrtl(ld(dist_sq)) * ps;
			pair_count += ps;
		}
	}

	cout << fixed << setprecision(15);
	cout << (sum / pair_count) << '\n';
	auto it = ans.begin();
	rep(i, 10000) {
		if(it == ans.end()) break;
		cout << (it->first) << ' ' << it->second << '\n';
		it++;
	}

	return 0;
}
accuracy: 1
time_ms: 1190
memory_kb: 199580
final_rank: 6

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

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

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

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

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

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

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
template<typename T>
void addv(vector<T>& v, int loc, T val) {
	if (loc >= v.size())v.resize(loc + 1, 0);
	v[loc] += val;
}
/*const int mn = 100005;
bool isp[mn];
vector<int> ps;
void init() {
	fill(isp + 2, isp + mn, true);
	for (int i = 2; i < mn; i++) {
		if (!isp[i])continue;
		ps.push_back(i);
		for (int j = 2 * i; j < mn; j += i) {
			isp[j] = false;
		}
	}
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	if (res == st.begin())return st.end();
	res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	return res;
}
using mP = pair<modint, modint>;


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


int get_premitive_root() {
	int primitive_root = 0;
	if (!primitive_root) {
		primitive_root = [&]() {
			set<int> fac;
			int v = mod - 1;
			for (ll i = 2; i * i <= v; i++) while (v % i == 0) fac.insert(i), v /= i;
			if (v > 1) fac.insert(v);
			for (int g = 1; g < mod; g++) {
				bool ok = true;
				for (auto i : fac) if (mod_pow(g, (mod - 1) / i) == 1) { ok = false; break; }
				if (ok) return g;
			}
			return -1;
		}();
	}
	return primitive_root;
}
const int proot = get_premitive_root();

typedef vector <modint> poly;
void dft(poly& f, bool inverse = false) {
	int n = f.size(); if (n == 1)return;

	static poly w{ 1 }, iw{ 1 };
	for (int m = w.size(); m < n / 2; m *= 2) {
		modint dw = mod_pow(proot, (mod - 1) / (4 * m)), dwinv = (modint)1 / dw;
		w.resize(m * 2); iw.resize(m * 2);
		for (int i = 0; i < m; i++)w[m + i] = w[i] * dw, iw[m + i] = iw[i] * dwinv;
	}
	if (!inverse) {
		for (int m = n; m >>= 1;) {
			for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
				for (int i = s; i < s + m; i++) {
					modint x = f[i], y = f[i + m] * w[k];
					f[i] = x + y, f[i + m] = x - y;
				}
			}
		}
	}
	else {
		for (int m = 1; m < n; m *= 2) {
			for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
				for (int i = s; i < s + m; i++) {
					modint x = f[i], y = f[i + m];
					f[i] = x + y, f[i + m] = (x - y) * iw[k];
				}
			}
		}
		modint n_inv = (modint)1 / (modint)n;
		for (modint& v : f)v *= n_inv;
	}
}
poly multiply(poly g, poly h) {
	int n = 1;
	int pi = 0, qi = 0;
	rep(i, g.size())if (g[i])pi = i;
	rep(i, h.size())if (h[i])qi = i;
	int sz = pi + qi + 2;
	while (n < sz)n *= 2;
	g.resize(n); h.resize(n);
	dft(g); dft(h);
	rep(i, n) {
		g[i] *= h[i];
	}
	dft(g, true);
	return g;
}


const int sz = 2048;
int c[sz][sz];
int r[sz][sz];
int cr[sz][sz];
void solve() {
	int n; cin >> n;
	rep(i, n)rep(j, n)cin >> c[i][j];
	int cnt = 0;
	rep(i, n)rep(j, n)cnt += c[i][j];
	rep(i, n)rep(j, n)r[i][j] = c[n - 1 - i][n - 1 - j];
	rep(i, sz) {
		poly p(sz);
		rep(j, sz)p[j] = c[i][j];
		dft(p);
		rep(j, sz)c[i][j] = p[j];

		rep(j, sz)p[j] = r[i][j];
		dft(p);
		rep(j, sz)r[i][j] = p[j];
	}
	rep(j, sz) {
		poly p(sz);
		rep(i, sz)p[i] = c[i][j];
		dft(p);
		rep(i, sz)c[i][j] = p[i];

		rep(i, sz)p[i] = r[i][j];
		dft(p);
		rep(i, sz)r[i][j] = p[i];
	}
	rep(i, sz)rep(j, sz)cr[i][j] = (ll)c[i][j] * r[i][j] % mod;
	
	rep(j, sz) {
		poly p(sz);
		rep(i, sz)p[i] = cr[i][j];
		dft(p, true);
		rep(i, sz)cr[i][j] = p[i];
	}
	rep(i, sz) {
		poly p(sz);
		rep(j, sz)p[j] = cr[i][j];
		dft(p, true);
		rep(j, sz)cr[i][j] = p[j];
	}
	/*rep(i, sz) {
		rep(j, sz)cout << cr[i][j] << " ";
		cout << "\n";
	}*/
	vector<LP> vp;
	rep(i, n)rep(j, n) {
		int d = i * i + j * j;
		int num = cr[i + n - 1][j + n - 1];
		if (i!=0&&j != 0)num += cr[i + n - 1][n - 1 - j];
		if (i == 0 && j == 0) {
			num -= cnt;
		}
		if (num != 0)vp.push_back({ d,num });
	}
	sort(all(vp));
	vector<LP> nvp;
	rep(i, vp.size()) {
		ll sum = vp[i].second;
		while (i + 1 < vp.size() && vp[i].first == vp[i + 1].first) {
			i++;
			sum += vp[i].second;
		}
		nvp.push_back({ vp[i].first,sum });
	}
	swap(vp, nvp);
	ld ans = 0;
	rep(i, vp.size()) {
		ans += vp[i].second * sqrtl(vp[i].first);
	}
	ans /= (ll)cnt * (cnt - 1) / 2;
	cout << ans << "\n";
	if(vp.size()>10000)vp.resize(10000);
	rep(i, vp.size()) {
		if (vp[i].first == 0)vp[i].second /= 2;
		cout << vp[i].first << " " << vp[i].second << "\n";
	}
}

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

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

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

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

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

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

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

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
template<typename T>
void addv(vector<T>& v, int loc, T val) {
	if (loc >= v.size())v.resize(loc + 1, 0);
	v[loc] += val;
}
/*const int mn = 100005;
bool isp[mn];
vector<int> ps;
void init() {
	fill(isp + 2, isp + mn, true);
	for (int i = 2; i < mn; i++) {
		if (!isp[i])continue;
		ps.push_back(i);
		for (int j = 2 * i; j < mn; j += i) {
			isp[j] = false;
		}
	}
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	if (res == st.begin())return st.end();
	res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	return res;
}
using mP = pair<modint, modint>;


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


int get_premitive_root() {
	int primitive_root = 0;
	if (!primitive_root) {
		primitive_root = [&]() {
			set<int> fac;
			int v = mod - 1;
			for (ll i = 2; i * i <= v; i++) while (v % i == 0) fac.insert(i), v /= i;
			if (v > 1) fac.insert(v);
			for (int g = 1; g < mod; g++) {
				bool ok = true;
				for (auto i : fac) if (mod_pow(g, (mod - 1) / i) == 1) { ok = false; break; }
				if (ok) return g;
			}
			return -1;
		}();
	}
	return primitive_root;
}
const int proot = get_premitive_root();

typedef vector <modint> poly;
void dft(poly& f, bool inverse = false) {
	int n = f.size(); if (n == 1)return;

	static poly w{ 1 }, iw{ 1 };
	for (int m = w.size(); m < n / 2; m *= 2) {
		modint dw = mod_pow(proot, (mod - 1) / (4 * m)), dwinv = (modint)1 / dw;
		w.resize(m * 2); iw.resize(m * 2);
		for (int i = 0; i < m; i++)w[m + i] = w[i] * dw, iw[m + i] = iw[i] * dwinv;
	}
	if (!inverse) {
		for (int m = n; m >>= 1;) {
			for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
				for (int i = s; i < s + m; i++) {
					modint x = f[i], y = f[i + m] * w[k];
					f[i] = x + y, f[i + m] = x - y;
				}
			}
		}
	}
	else {
		for (int m = 1; m < n; m *= 2) {
			for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
				for (int i = s; i < s + m; i++) {
					modint x = f[i], y = f[i + m];
					f[i] = x + y, f[i + m] = (x - y) * iw[k];
				}
			}
		}
		modint n_inv = (modint)1 / (modint)n;
		for (modint& v : f)v *= n_inv;
	}
}
poly multiply(poly g, poly h) {
	int n = 1;
	int pi = 0, qi = 0;
	rep(i, g.size())if (g[i])pi = i;
	rep(i, h.size())if (h[i])qi = i;
	int sz = pi + qi + 2;
	while (n < sz)n *= 2;
	g.resize(n); h.resize(n);
	dft(g); dft(h);
	rep(i, n) {
		g[i] *= h[i];
	}
	dft(g, true);
	return g;
}


const int sz = 2048;
int c[2048][2048];
int r[2048][2048];
int cr[2048][2048];
void solve() {
	int n; cin >> n;
	rep(i, n)rep(j, n)cin >> c[i][j];
	int cnt = 0;
	rep(i, n)rep(j, n)cnt += c[i][j];
	rep(i, n)rep(j, n)r[i][j] = c[n - 1 - i][n - 1 - j];
	rep(i, sz) {
		poly p(sz);
		rep(j, sz)p[j] = c[i][j];
		dft(p);
		rep(j, sz)c[i][j] = p[j];

		rep(j, sz)p[j] = r[i][j];
		dft(p);
		rep(j, sz)r[i][j] = p[j];
	}
	rep(j, sz) {
		poly p(sz);
		rep(i, sz)p[i] = c[i][j];
		dft(p);
		rep(i, sz)c[i][j] = p[i];

		rep(i, sz)p[i] = r[i][j];
		dft(p);
		rep(i, sz)r[i][j] = p[i];
	}
	rep(i, sz)rep(j, sz)cr[i][j] = (ll)c[i][j] * r[i][j] % mod;
	
	rep(j, sz) {
		poly p(sz);
		rep(i, sz)p[i] = cr[i][j];
		dft(p, true);
		rep(i, sz)cr[i][j] = p[i];
	}
	rep(i, sz) {
		poly p(sz);
		rep(j, sz)p[j] = cr[i][j];
		dft(p, true);
		rep(j, sz)cr[i][j] = p[j];
	}
	/*rep(i, sz) {
		rep(j, sz)cout << cr[i][j] << " ";
		cout << "\n";
	}*/
	vector<P> vp;
	rep(i, n)rep(j, n) {
		int d = i * i + j * j;
		int num = cr[i + n - 1][j + n - 1];
		if (i!=0&&j != 0)num += cr[i + n - 1][n - 1 - j];
		if (i == 0 && j == 0) {
			num -= cnt;
		}
		if (num != 0)vp.push_back({ d,num });
	}
	sort(all(vp));
	vector<P> nvp;
	rep(i, vp.size()) {
		int sum = vp[i].second;
		while (i + 1 < vp.size() && vp[i].first == vp[i + 1].first) {
			i++;
			sum += vp[i].second;
		}
		nvp.push_back({ vp[i].first,sum });
	}
	swap(vp, nvp);
	ld ans = 0;
	rep(i, vp.size()) {
		ans += vp[i].second * sqrt(vp[i].first);
	}
	ans /= (ll)cnt * (cnt - 1) / 2;
	cout << ans << "\n";
	if(vp.size()>10000)vp.resize(10000);
	rep(i, vp.size()) {
		if (vp[i].first == 0)vp[i].second /= 2;
		cout << vp[i].first << " " << vp[i].second << "\n";
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//while(true)
	//useexpr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 0.90625
time_ms: 830
memory_kb: 76516
final_rank: 14

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

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

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

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

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

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

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
template<typename T>
void addv(vector<T>& v, int loc, T val) {
	if (loc >= v.size())v.resize(loc + 1, 0);
	v[loc] += val;
}
/*const int mn = 100005;
bool isp[mn];
vector<int> ps;
void init() {
	fill(isp + 2, isp + mn, true);
	for (int i = 2; i < mn; i++) {
		if (!isp[i])continue;
		ps.push_back(i);
		for (int j = 2 * i; j < mn; j += i) {
			isp[j] = false;
		}
	}
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	if (res == st.begin())return st.end();
	res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	return res;
}
using mP = pair<modint, modint>;


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


int get_premitive_root() {
	int primitive_root = 0;
	if (!primitive_root) {
		primitive_root = [&]() {
			set<int> fac;
			int v = mod - 1;
			for (ll i = 2; i * i <= v; i++) while (v % i == 0) fac.insert(i), v /= i;
			if (v > 1) fac.insert(v);
			for (int g = 1; g < mod; g++) {
				bool ok = true;
				for (auto i : fac) if (mod_pow(g, (mod - 1) / i) == 1) { ok = false; break; }
				if (ok) return g;
			}
			return -1;
		}();
	}
	return primitive_root;
}
const int proot = get_premitive_root();

typedef vector <modint> poly;
void dft(poly& f, bool inverse = false) {
	int n = f.size(); if (n == 1)return;

	static poly w{ 1 }, iw{ 1 };
	for (int m = w.size(); m < n / 2; m *= 2) {
		modint dw = mod_pow(proot, (mod - 1) / (4 * m)), dwinv = (modint)1 / dw;
		w.resize(m * 2); iw.resize(m * 2);
		for (int i = 0; i < m; i++)w[m + i] = w[i] * dw, iw[m + i] = iw[i] * dwinv;
	}
	if (!inverse) {
		for (int m = n; m >>= 1;) {
			for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
				for (int i = s; i < s + m; i++) {
					modint x = f[i], y = f[i + m] * w[k];
					f[i] = x + y, f[i + m] = x - y;
				}
			}
		}
	}
	else {
		for (int m = 1; m < n; m *= 2) {
			for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
				for (int i = s; i < s + m; i++) {
					modint x = f[i], y = f[i + m];
					f[i] = x + y, f[i + m] = (x - y) * iw[k];
				}
			}
		}
		modint n_inv = (modint)1 / (modint)n;
		for (modint& v : f)v *= n_inv;
	}
}
poly multiply(poly g, poly h) {
	int n = 1;
	int pi = 0, qi = 0;
	rep(i, g.size())if (g[i])pi = i;
	rep(i, h.size())if (h[i])qi = i;
	int sz = pi + qi + 2;
	while (n < sz)n *= 2;
	g.resize(n); h.resize(n);
	dft(g); dft(h);
	rep(i, n) {
		g[i] *= h[i];
	}
	dft(g, true);
	return g;
}


const int sz = 2048;
int c[2048][2048];
int r[2048][2048];
int cr[2048][2048];
void solve() {
	int n; cin >> n;
	rep(i, n)rep(j, n)cin >> c[i][j];
	int cnt = 0;
	rep(i, n)rep(j, n)cnt += c[i][j];
	rep(i, n)rep(j, n)r[i][j] = c[n - 1 - i][n - 1 - j];
	rep(i, sz) {
		poly p(sz);
		rep(j, sz)p[j] = c[i][j];
		dft(p);
		rep(j, sz)c[i][j] = p[j];

		rep(j, sz)p[j] = r[i][j];
		dft(p);
		rep(j, sz)r[i][j] = p[j];
	}
	rep(j, sz) {
		poly p(sz);
		rep(i, sz)p[i] = c[i][j];
		dft(p);
		rep(i, sz)c[i][j] = p[i];

		rep(i, sz)p[i] = r[i][j];
		dft(p);
		rep(i, sz)r[i][j] = p[i];
	}
	rep(i, sz)rep(j, sz)cr[i][j] = (ll)c[i][j] * r[i][j] % mod;
	
	rep(j, sz) {
		poly p(sz);
		rep(i, sz)p[i] = cr[i][j];
		dft(p, true);
		rep(i, sz)cr[i][j] = p[i];
	}
	rep(i, sz) {
		poly p(sz);
		rep(j, sz)p[j] = cr[i][j];
		dft(p, true);
		rep(j, sz)cr[i][j] = p[j];
	}
	/*rep(i, sz) {
		rep(j, sz)cout << cr[i][j] << " ";
		cout << "\n";
	}*/
	vector<P> vp;
	rep(i, n)rep(j, n) {
		int d = i * i + j * j;
		int num = cr[i + n - 1][j + n - 1];
		if (i!=0&&j != 0)num += cr[i + n - 1][n - 1 - j];
		if (i == 0 && j == 0) {
			num -= cnt;
		}
		if (num != 0)vp.push_back({ d,num });
	}
	sort(all(vp));
	vector<P> nvp;
	rep(i, vp.size()) {
		int sum = vp[i].second;
		while (i + 1 < vp.size() && vp[i].first == vp[i + 1].first) {
			i++;
			sum += vp[i].second;
		}
		nvp.push_back({ vp[i].first,sum });
	}
	swap(vp, nvp);
	ld ans = 0;
	rep(i, vp.size()) {
		ans += vp[i].second * sqrt(vp[i].first);
	}
	ans /= cnt * (cnt - 1) / 2;
	cout << ans << "\n";
	if(vp.size()>10000)vp.resize(10000);
	rep(i, vp.size()) {
		if (vp[i].first == 0)vp[i].second /= 2;
		cout << vp[i].first << " " << vp[i].second << "\n";
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//while(true)
	//useexpr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 0.515625
time_ms: 760
memory_kb: 71432
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAXN 1025
#define MAXM 8200005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL; 
typedef long double ld;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
const int mo=998244353;
const int inv2=5e8+4;
const int jzm=23333;
const int zero=20000;
const int n1=1000;
const int lim=100000000;
const int orG=3,ivG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-12;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1)t=1ll*t*a%p;a=1ll*a*a%p;s>>=1;}return t;}
int n,val[MAXN][MAXN],f[MAXM],g[MAXM],rev[MAXM],tot;LL num=0;
double ans,summ;vector<pii>answer;
void NTT(int *A,int lim,int typ){
	for(int i=0;i<lim;i++)if(i<rev[i])swap(A[i],A[rev[i]]);
	for(int mid=1;mid<lim;mid<<=1){
		const int W=qkpow(typ^1?ivG:orG,(mo-1)/(mid<<1),mo);
		for(int i=mid<<1,j=0;j<lim;j+=i)
			for(int k=j,Wn=1;k<j+mid;k++,Wn=1ll*Wn*W%mo){
				const int x=A[k],y=1ll*Wn*A[k+mid]%mo;
				A[k]=add(x,y,mo);A[k+mid]=add(x,mo-y,mo);
			}
	}
	if(typ^-1)return ;const int tmp=qkpow(lim,mo-2,mo);
	for(int i=0;i<lim;i++)A[i]=1ll*tmp*A[i]%mo;
}
signed main(){
	read(n);int lim=1,len=0,cnt=0;while(lim<4*n*n)lim<<=1,len++;
	for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<len-1);
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)read(val[i][j]),f[(i-1)*(n+n)+j-1]=g[(n-i)*(n+n)+n-j]=val[i][j],cnt+=val[i][j];
	NTT(f,lim,1);NTT(g,lim,1);for(int i=0;i<lim;i++)f[i]=1ll*f[i]*g[i]%mo;NTT(f,lim,-1);
	for(int i=0;i<lim;i++)if(f[i]){
		int x=Fabs(i/(n+n)-n+1),y=Fabs(i%(n+n)-n+1);
		ans+=sqrt(1.0*x*x+1.0*y*y)*f[i];num+=f[i];
		answer.pb(mkpr(x*x+y*y,f[i]));
	}
	num-=cnt;printf("%.9f\n",ans/num);
	sort(answer.begin(),answer.end());int siz=answer.size();
	for(int i=0,j=-1;i<siz;i=j+1){
		int now=answer[i].fir;LL nm=0;
		while(j<siz-1&&now==answer[j+1].fir)
			j++,nm+=answer[j].sec;
		if(now==0)nm-=cnt;if(!nm)continue;
		printf("%d %lld\n",now,nm/2LL);tot++;
		if(tot==10000)break;
	}
	return 0;
}
accuracy: 1
time_ms: 920
memory_kb: 98724
final_rank: 2

code_snippet: #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cmath>
using namespace std;
# define rep(i,a,b) for(int i=(a); i<=(b); ++i)
# define drep(i,a,b) for(int i=(a); i>=(b); --i)
typedef long long llong;
inline int readint(){
	int a = 0, c = getchar(), f = 1;
	for(; !isdigit(c); c=getchar())
		if(c == '-') f = -f;
	for(; isdigit(c); c=getchar())
		a = (a<<3)+(a<<1)+(c^48);
	return a*f;
}
inline int ABS(const int x){
	return (x < 0) ? (-x) : x;
}

const int MOD = 998244353;
inline void modAddUp(int &x,const int y){
	if((x += y) >= MOD) x -= MOD;
}
inline int qkpow(llong b,int q){
	llong a = 1;
	for(; q; q>>=1,b=b*b%MOD)
		if(q&1) a = a*b%MOD;
	return static_cast<int>(a);
}

const int LOGMOD = 30;
int g[LOGMOD], inv2[LOGMOD];
void prepare(){
	int p = MOD-1, x = 0; inv2[0] = 1;
	for(inv2[1]=(MOD+1)>>1; !(p&1); p>>=1,++x)
		inv2[x+1] = int(llong(inv2[x])*inv2[1]%MOD);
	for(g[x]=qkpow(3,p); x; --x) g[x-1] = int(llong(g[x])*g[x]%MOD);
}

const int MAXN = 1<<22;
void NTT(int a[],int n){
	for(int w=1<<n>>1,x=n; x; w>>=1,--x)
	for(int *p=a; p!=a+(1<<n); p+=(w<<1))
	for(int i=0,v=1; i!=w; ++i){
		const int t = p[i+w]; // backup
		p[i+w] = int(llong(p[i]+MOD-t)*v%MOD);
		modAddUp(p[i],t); v = int(llong(v)*g[x]%MOD);
	}
}
void DNTT(int a[],int n){
	for(int w=1,x=1; x<=n; w<<=1,++x)
	for(int *p=a; p!=a+(1<<n); p+=(w<<1))
	for(int i=0,v=1; i!=w; ++i){
		const int t = int(llong(v)*p[i+w]%MOD);
		p[i+w] = (p[i]+MOD-t)%MOD;
		modAddUp(p[i],t); v = int(llong(v)*g[x]%MOD);
	}
	reverse(a+1,a+(1<<n));
	for(int *p=a; p!=a+(1<<n); ++p)
		*p = int(llong(*p)*inv2[n]%MOD);
}

int a[MAXN], b[MAXN], c[MAXN];
# define sqr(x) ((x)*(x))
int main(){
	prepare();
	int n = readint(), all = 0;
	const int LEN = (n<<1)-1;
	for(int i=0; i!=n; ++i) for(int j=0; j!=n; ++j)
		all += (a[i*LEN+j] = b[(n-1-i)*LEN+(n-1-j)] = readint());
	int N; for(N=0; (1<<N)<LEN*LEN; ++N);
	NTT(a,N), NTT(b,N);
	for(int i=0; i!=(1<<N); ++i)
		a[i] = int(llong(a[i])*b[i]%MOD);
	DNTT(a,N); double ave = 0;
	for(int i=0; i!=LEN; ++i) for(int j=0; j!=LEN; ++j){
		const int val = sqr(i-n+1)+sqr(j-n+1);
		c[val] += a[i*LEN+j], ave += a[i*LEN+j]*sqrt(val);
		// if(a[i*LEN+j]) printf("%d -> %d\n",a[i*LEN+j],val);
	}
	printf("%.12f\n",ave/(llong(all-1)*all));
	int tot = 0; c[0] -= all;
	for(int i=0; i!=MAXN; ++i) if(c[i]){
		printf("%d %d\n",i,c[i]>>1);
		if((++ tot) == 10000) break;
	}
	return 0;
}
accuracy: 0.90625
time_ms: 560
memory_kb: 44488
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define rep(i, l, r) for(int i=l, _=r; i<=_; ++i)
#pragma GCC diagnostic ignored "-Wparentheses"
using namespace std;
typedef long long ll;
inline int read() {
	int res=0; bool k=1; char ch;
	while(!isdigit(ch=getchar())) k=ch^45;
	do res=res*10+(ch&15); while(isdigit(ch=getchar()));
	return k? res: -res;
}
const double pi=acos(-1);
const int mN=1<<22|9, N=1<<22;
int n;
ll sum, ans[mN];

struct Cpl {
	double a, b;
	Cpl (double a=0, double b=0): a(a), b(b) {}
    Cpl operator + (const Cpl &y) const {return Cpl(a+y.a, b+y.b);}
    Cpl operator - (const Cpl &y) const {return Cpl(a-y.a, b-y.b);}
    Cpl operator * (const Cpl &y) const {return Cpl(a*y.a-b*y.b, a*y.b+b*y.a);}
} f[mN], g[mN], omega[mN];

void FFT(Cpl *a, int n, bool k) {
	if(n==1) return;
	static Cpl tmp[mN];
	Cpl *b=a+(n>>1), x, y;
	rep(i, 0, n-1) tmp[i]=a[i];
	rep(i, 0, n-1>>1) a[i]=tmp[i<<1], b[i]=tmp[i<<1|1];
	FFT(a, n>>1, k), FFT(b, n>>1, k);
	rep(i, 0, n-1>>1) x=a[i], y=omega[k? N-N/n*i: N/n*i]*b[i], a[i]=x+y, b[i]=x-y;
}
inline int sqr(int x) {return x*x;}

int main() {
	rep(i, 0, N) omega[i]=Cpl(cos(2*pi/N*i), sin(2*pi/N*i));

	rep(i, 1, n=read()) rep(j, 1, n) sum+=f[(i-1)*n*2+j-1].a=g[(n-i)*n*2+n-j].a=read();
	FFT(f, N, 0), FFT(g, N, 0);
	rep(i, 0, N-1) f[i]=f[i]*g[i];
	FFT(f, N, 1);
	rep(i, 0, (n-1)*(n<<1|1)<<1) ans[sqr(i/(2*n)-n+1)+sqr(i%(2*n)-n+1)]+=(ll) (f[i].a/N+0.3);
	ans[0]-=sum;
	double ave=0;
	rep(i, 1, n*n*2) ave+=ans[i]*sqrt(i);
	printf("%.10lf\n", ave/sum/(sum-1));
	for(int i=0, j=0, _=n*n<<1; i<=_; ++i) if(ans[i]>0 && (printf("%d %lld\n", i, ans[i]/2), ++j==10000)) break;
	return 0;
}
accuracy: 1
time_ms: 1770
memory_kb: 282364
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define pi 3.141592653589793238
using namespace std;
int n,m,r[6500004],lim,len;
struct Complex{
    double x,y;
    Complex(double xx=0,double yy=0)
    {x=xx,y=yy;}
}a[6500004],b[6500004],w[6500004];
inline Complex operator + (Complex a,Complex b){
    return Complex(a.x+b.x,a.y+b.y);
}
inline Complex operator - (Complex a,Complex b){
    return Complex(a.x-b.x,a.y-b.y);
}
inline Complex operator * (Complex a,Complex b){
    return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
inline void swap(Complex &a,Complex &b){
    Complex t=a;a=b;b=t;
}
inline void FFT(Complex f[],int id){
    for (int i=0;i<lim;i++){
        if (i<r[i]) swap(f[r[i]],f[i]);
    }
    w[0].x=1;w[0].y=0;
    for (int len=1;len<lim;len<<=1){
    	Complex gen(cos(pi/len),id*sin(pi/len));
    	for (int i=1;i<len;i++) w[i]=w[i-1]*gen;
        for (int i=0;i<lim;i+=len<<1){
            Complex *f1=f+i,*f2=f1+len;
            for (int j=0;j<len;j++){
                Complex x=f1[j],y=f2[j]*w[j];
                f1[j]=x+y;f2[j]=x-y;
            }
        }
    }
    if (id==1) return;
    for (int i=0;i<lim;i++) f[i].x=(ll)(f[i].x/(double)lim+0.5);
}
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
int T,N,Q,has[1010101],C[1010][1010];
ll ans[2010000];
double _ans;
inline int id(int x,int y){
	return (x-1)*2*N+y-1;
}
int main(){
	N=read();
	ll __ans=0;
	for (int i=1;i<=N;i++){
		for (int j=1;j<=N;j++){
			C[i][j]=read();
			a[id(i,j)].x=C[i][j];
			b[id(N,N)-id(i,j)].x=C[i][j];
			ans[0]+=(C[i][j]-1)*(C[i][j])/2;
			__ans+=C[i][j];
		}
	} 
	lim=1;
	int len=0;
	while (lim<=(id(N,N)*2+1)) lim<<=1,len++;
	for (int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(len-1));
	FFT(a,1);FFT(b,1);
	for (int i=0;i<lim;i++) a[i]=a[i]*b[i];
	FFT(a,-1);
	for (int i=1;i<=id(N,N)-id(1,1);i++){
		int detx=(i+N)/(2*N),dety=abs(i-2*N*detx);
		_ans+=sqrt(1.0*detx*detx+1.0*dety*dety)*1.0*a[i+id(N,N)].x;
		ans[detx*detx+dety*dety]+=(ll)a[i+id(N,N)].x;
	}
	printf("%.10lf\n",1.0*_ans/(double)(__ans*(__ans-1)/2));
	for (int i=0;i<=N*N;i++){
		if (ans[i]){
			cout<<i<<" "<<ans[i]<<endl;
		}
	}
}
accuracy: 0.046875
time_ms: 70
memory_kb: 308288
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define pi 3.141592653589793238
using namespace std;
int n,m,r[6500004],lim,len;
struct Complex{
    double x,y;
    Complex(double xx=0,double yy=0)
    {x=xx,y=yy;}
}a[6500004],b[6500004],w[6500004];
inline Complex operator + (Complex a,Complex b){
    return Complex(a.x+b.x,a.y+b.y);
}
inline Complex operator - (Complex a,Complex b){
    return Complex(a.x-b.x,a.y-b.y);
}
inline Complex operator * (Complex a,Complex b){
    return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
inline void swap(Complex &a,Complex &b){
    Complex t=a;a=b;b=t;
}
inline void FFT(Complex f[],int id){
    for (int i=0;i<lim;i++){
        if (i<r[i]) swap(f[r[i]],f[i]);
    }
    w[0].x=1;w[0].y=0;
    for (int len=1;len<lim;len<<=1){
    	Complex gen(cos(pi/len),id*sin(pi/len));
    	for (int i=1;i<len;i++) w[i]=w[i-1]*gen;
        for (int i=0;i<lim;i+=len<<1){
            Complex *f1=f+i,*f2=f1+len;
            for (int j=0;j<len;j++){
                Complex x=f1[j],y=f2[j]*w[j];
                f1[j]=x+y;f2[j]=x-y;
            }
        }
    }
    if (id==1) return;
    for (int i=0;i<lim;i++) f[i].x=(ll)(f[i].x/(double)lim+0.5);
}
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
int T,N,Q,has[1010101],C[1010][1010];
ll ans[2010000];
double _ans;
inline int id(int x,int y){
	return (x-1)*2*N+y;
}
int main(){
	N=read();
	ll __ans=0;
	for (int i=1;i<=N;i++){
		for (int j=1;j<=N;j++){
			C[i][j]=read();
			a[id(i,j)].x=C[i][j];
			b[id(N,N)-id(i,j)].x=C[i][j];
			ans[0]+=(C[i][j]-1)*(C[i][j])/2;
			__ans+=(C[i][j]-1)*(C[i][j])/2;
		}
	} 
	lim=1;
	int len=0;
	while (lim<=(id(N,N)*2+1)) lim<<=1,len++;
	for (int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(len-1));
	FFT(a,1);FFT(b,1);
	for (int i=0;i<lim;i++) a[i]=a[i]*b[i];
	FFT(a,-1);
	for (int i=1;i<=id(N,N)-id(1,1);i++){
		int detx=(i+N)/(2*N),dety=abs(i-2*N*detx);
		_ans+=sqrt(1.0*detx*detx+1.0*dety*dety)*1.0*a[i+id(N,N)].x;
		__ans+=a[i+id(N,N)].x;
		ans[detx*detx+dety*dety]+=(ll)a[i+id(N,N)].x;
	}
	printf("%.10lf\n",1.0*_ans/__ans);
	for (int i=0;i<=N*N;i++){
		if (ans[i]){
			cout<<i<<" "<<ans[i]<<endl;
		}
	}
}
accuracy: 0.046875
time_ms: 70
memory_kb: 308264
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define pi 3.141592653589793238
using namespace std;
int n,m,r[6000004],lim,len;
struct Complex{
    double x,y;
    Complex(double xx=0,double yy=0)
    {x=xx,y=yy;}
}a[6000004],b[6000004],w[6000004];
inline Complex operator + (Complex a,Complex b){
    return Complex(a.x+b.x,a.y+b.y);
}
inline Complex operator - (Complex a,Complex b){
    return Complex(a.x-b.x,a.y-b.y);
}
inline Complex operator * (Complex a,Complex b){
    return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
inline void swap(Complex &a,Complex &b){
    Complex t=a;a=b;b=t;
}
inline void FFT(Complex f[],int id){
    for (int i=0;i<lim;i++){
        if (i<r[i]) swap(f[r[i]],f[i]);
    }
    w[0].x=1;w[0].y=0;
    for (int len=1;len<lim;len<<=1){
    	Complex gen(cos(pi/len),id*sin(pi/len));
    	for (int i=1;i<len;i++) w[i]=w[i-1]*gen;
        for (int i=0;i<lim;i+=len<<1){
            Complex *f1=f+i,*f2=f1+len;
            for (int j=0;j<len;j++){
                Complex x=f1[j],y=f2[j]*w[j];
                f1[j]=x+y;f2[j]=x-y;
            }
        }
    }
    if (id==1) return;
    for (int i=0;i<lim;i++) f[i].x=(ll)(f[i].x/(double)lim+0.5);
}
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
int T,N,Q,has[1010101],C[1010][1010];
ll ans[1010000];
double _ans;
inline int id(int x,int y){
	return x*2*N+y;
}
int main(){
	N=read();
	ll __ans=0;
	for (int i=1;i<=N;i++){
		for (int j=1;j<=N;j++){
			C[i][j]=read();
			a[id(i,j)].x=C[i][j];
			b[id(N,N)-id(i,j)].x=C[i][j];
			ans[0]+=(C[i][j]-1)*(C[i][j])/2;
			__ans+=(C[i][j]-1)*(C[i][j])/2;
		}
	} 
	lim=1;
	int len=0;
	while (lim<=(id(N,N)*2+1)) lim<<=1,len++;
	for (int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(len-1));
	FFT(a,1);FFT(b,1);
	for (int i=0;i<lim;i++) a[i]=a[i]*b[i];
	FFT(a,-1);
	for (int i=1;i<=id(N,N)-id(1,1);i++){
		int detx=(i+N)/(2*N),dety=abs(i-2*N*detx);
		_ans+=sqrt(1.0*detx*detx+1.0*dety*dety)*1.0*a[i+id(N,N)].x;
		__ans+=a[i+id(N,N)].x;
		ans[detx*detx+dety*dety]+=(ll)a[i+id(N,N)].x;
	}
	printf("%.10lf\n",1.0*_ans/__ans);
	for (int i=0;i<=N*N;i++){
		if (ans[i]){
			cout<<i<<" "<<ans[i]<<endl;
		}
	}
}
accuracy: 0.046875
time_ms: 60
memory_kb: 284820
final_rank: 18

code_snippet: #include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef double db;
typedef long long ll;
const db pi = acos(-1.0);
const int N = 1 << 21 | 5; // 2n^2
const int M = 1 << 22 | 5;
struct comp_t {
	db x, y;
	comp_t(db a = 0, db b = 0) : x(a), y(b) {}
	comp_t operator + (const comp_t &b) const { return (comp_t) {x + b.x, y + b.y}; }
	comp_t operator - (const comp_t &b) const { return (comp_t) {x - b.x, y - b.y}; }
	comp_t operator * (const comp_t &b) const { return (comp_t) {x * b.x - y * b.y, b.x * y + x * b.y}; }
	inline void rev() { y = -y; }
} wnk[M];
int lim, r[M], A[M], B[M], n;
ll ans[N];
void init(int len) {
	int l = 0;
	for(lim = 1; lim <= len; lim <<= 1) l ++;
	for(int i = 1; i < lim; i ++) {
		r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
	}
	wnk[0] = comp_t(1, 0);
	wnk[1] = comp_t(cos(2 * pi / lim), sin(2 * pi / lim));
	for(int i = 2; i < lim; i ++) wnk[i] = wnk[i - 1] * wnk[1];
}
void fft(comp_t *a, int t) {
	for(int i = 1; i < lim; i ++)
		if(i < r[i]) swap(a[i], a[r[i]]);
	for(int i = 1; i < lim; i <<= 1) {
		for(int j = 0; j < lim; j += i << 1) {
			for(int k = 0; k < i; k ++) {
				comp_t y = wnk[lim / (i << 1) * k];
				if(t == -1) y.rev();
				comp_t p = a[j + k], q = y * a[j + k + i];
				a[j + k] = p + q; a[j + k + i] = p - q;
			}
		}
	}
}
ll *const_mul(int *a, int *b, int n, int m) {
	static ll ans[M];
	static comp_t A[M], B[M];
	init(n + m);
	for(int i = 0; i < lim; i ++) A[i] = comp_t(i <= n ? a[i] : 0);
	for(int i = 0; i < lim; i ++) B[i] = comp_t(i <= m ? b[i] : 0);
	fft(A, 1); fft(B, 1);
	for(int i = 0; i < lim; i ++) A[i] = A[i] * B[i];
	fft(A, -1);
	for(int i = 0; i <= n + m; i ++) ans[i] = (ll) (A[i].x / lim + 0.5);
	return ans;
}
int main() {
	scanf("%d", &n);
	int ma = n * (2 * n - 1) - 1, s = 0;
	for(int x, i = 0; i < n; i ++) {
		for(int j = 0; j < n; j ++) {
			scanf("%d", &x); s += x;
			A[2 * n * i + j] += x;
		}
	}
	copy(A, A + ma + 1, B); reverse(B, B + ma + 1);
	ll *t = const_mul(A, B, ma, ma);
	for(int i = 0; i <= (ma << 1); i ++) if(t[i]) {
		ll val = i - ma, dy = (val % (n * 2) + (n * 2)) % (n * 2);
		if(dy > n) dy -= n * 2;
		ll dx = (val - dy) / (n * 2);
		ans[dx * dx + dy * dy] += t[i];
	}
	ll tot = 0; db sum = 0;
	for(int i = 0; i < 2 * n * n; i ++) if(ans[i]) {
		if(!i) ans[i] -= s;
		ans[i] /= 2;
		sum += sqrt(i) * ans[i]; tot += ans[i];
	}
	printf("%.10f\n", (double) (sum / tot));
	int pr_lim = 10000;
	for(int i = 0; i < 2 * n * n; i ++) if(ans[i]) {
		printf("%d %lld\n", i, ans[i]);
		if(-- pr_lim == 0) break ;
	}
	return 0;
}
accuracy: 1
time_ms: 2170
memory_kb: 281024
final_rank: 9

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




#define MAX 25
typedef complex<double> COMPLEX;
typedef vector<COMPLEX> V;
typedef vector<V> MATRIX;


ll ans[3000005];

struct Info{
	Info(int arg_left,int arg_right){
		left = arg_left;
		right = arg_right;
	}
	int left,right;
};

int POW[MAX];
int LR_rev[3000005];
vector<Info> info;
vector<COMPLEX> MULT[MAX];


void calc_swap_pair(int N,int num_pow){

	LR_rev[0] = 0;

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

		if(i%2 == 1){

			LR_rev[i] += LR_rev[i-1]+POW[num_pow-1]; //1を足す代わりにPOW[num_pow-1]を足す

		}else{

			LR_rev[i] = LR_rev[i/2]/2; //半分のインデックスの値に、2を掛ける代わりに2で割る
		}

		if(i < LR_rev[i]){
			info.push_back(Info(i,LR_rev[i]));
		}
	}
}

void calc_COMPLEX(int N){

	for(int LEN = 2,num_pow = 0; LEN <= N; LEN *= 2,num_pow++){

		MULT[num_pow].resize(LEN/2);

		MULT[num_pow][0] = COMPLEX(cos(0),sin(0));

		COMPLEX mult = COMPLEX(cos((2*M_PI)/LEN),sin((2*M_PI)/LEN));

		for(int i = 1; i < LEN/2; i++){

			if(i%2 == 1){
				MULT[num_pow][i] = MULT[num_pow][i-1]*mult;
			}else{
				MULT[num_pow][i] = MULT[num_pow-1][i/2];
			}
		}
	}
}

//離散フーリエ変換
vector<COMPLEX> DFT(vector<COMPLEX> A) {

	int N = A.size();

	/*偶数項を左に、奇数項を右に仕分けるルールで要素数1まで仕分けした場合の、
	 * 最終結果を先に作っておく(ビットが左右反転したものがその位置に来る)*/
	for(int i = 0; i < info.size(); i++){

		swap(A[info[i].left],A[info[i].right]);
	}

	COMPLEX a,add;

	for(int LEN = 2,num_pow = 0; LEN <= N; LEN *= 2,num_pow++){

		for(int start = 0; start < N; start += LEN){
			for(int i = 0; i < LEN/2; i++){
				//マージソートの容量で、配列を更新していく
				a = A[start+i];
				add = MULT[num_pow][i]*A[start+LEN/2+i];

				A[start+i] = a+add;
				A[start+LEN/2+i] = a-add;
			}
		}
	}
	return A;
}

//離散逆フーリエ変換
vector<COMPLEX> inverseDFT(vector<COMPLEX> A){

	int N = A.size();

	vector<COMPLEX> TMP = DFT(A);

	//係数を入れ替える&サイズNで各要素を割る
	vector<COMPLEX> RET(N);

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

		RET[i] = TMP[(N-i)%N];
		RET[i] = RET[i]/COMPLEX(N,0);
	}

	return RET;
}

//AとBのサイズは、大きい方に揃えておく
MATRIX convolution2D(MATRIX A,MATRIX B){

	int SIZE = A.size();

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

		if(SIZE == POW[i]){
			calc_swap_pair(SIZE,i);
					break;
		}
	}
	calc_COMPLEX(SIZE);

	MATRIX RET(SIZE,V(SIZE));

	//行についてのフーリエ変換
	for(int row = 0; row < SIZE; row++){

		A[row] = DFT(A[row]);
		B[row] = DFT(B[row]);
	}

	//列についてのフーリエ変換を行単位で処理するため、転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(A[row][col],A[col][row]);
			swap(B[row][col],B[col][row]);
		}
	}

	//列についてのフーリエ変換
	for(int row = 0; row < SIZE; row++){

		A[row] = DFT(A[row]);
		B[row] = DFT(B[row]);
	}

	//元に戻すため、再転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(A[row][col],A[col][row]);
			swap(B[row][col],B[col][row]);
		}
	}

	//ここまでの結果を計算
	for(int row = 0; row < SIZE; row++){
		for(int col = 0; col < SIZE; col++){

			RET[row][col] = A[row][col]*B[row][col];
		}
	}

	//各行をフーリエ逆変換
	for(int row = 0; row < SIZE; row++){

		RET[row] = inverseDFT(RET[row]);
	}

	//転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(RET[row][col],RET[col][row]);
		}
	}

	for(int row = 0; row < SIZE; row++){

		RET[row] = inverseDFT(RET[row]);
	}

	//元に戻すため、再転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(RET[row][col],RET[col][row]);
		}
	}

	return RET;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i < MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N;
	scanf("%lld",&N);

	ll SIZE = 1;
	while(SIZE < 2*N)SIZE *= 2;

	MATRIX A(SIZE,V(SIZE));
	MATRIX B(SIZE,V(SIZE)); //上下左右反転

	ll tmp;
	ll first_sum = 0;

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			scanf("%lld",&tmp);
			first_sum += tmp;

			A[row][col] += tmp;
			B[(N-1)-row][(N-1)-col] += tmp;
		}
	}

	MATRIX ret = convolution2D(A,B);

	ll maximum = (N-1)*(N-1)*2;

	for(ll i = 0; i <= maximum; i++){

		ans[i] = 0;
	}

	double sum = 0;
	ll all_num = 0;

	for(ll row = 0; row <= 2*N-2; row++){
		for(ll col = 0; col <= 2*N-2; col++){

			ll dist = ((N-1)-row)*((N-1)-row)+((N-1)-col)*((N-1)-col);
			ll num = (ll)round(ret[row][col].real());

			all_num += num;

			sum += num*sqrt((double)dist);

			ans[dist] += num;
		}
		printf("\n");
	}

	all_num -= first_sum;

	printf("%.10lf\n",sum/all_num);

	int count = 0;

	ans[0] -= first_sum;

	for(ll i = 0; i <= maximum; i++){

		if(ans[i] == 0)continue;

		printf("%lld %lld\n",i,ans[i]/2);

		count++;
		if(count == 10000)break;
	}

	return 0;
}
accuracy: 1
time_ms: 1150
memory_kb: 347704
final_rank: 8

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




#define MAX 25
typedef complex<double> COMPLEX;
typedef vector<COMPLEX> V;
typedef vector<V> MATRIX;


ll ans[2000005];

struct Info{
	Info(int arg_left,int arg_right){
		left = arg_left;
		right = arg_right;
	}
	int left,right;
};

int POW[MAX];
int LR_rev[2000005];
vector<Info> info;
vector<COMPLEX> MULT[MAX];


void calc_swap_pair(int N,int num_pow){

	LR_rev[0] = 0;

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

		if(i%2 == 1){

			LR_rev[i] += LR_rev[i-1]+POW[num_pow-1]; //1を足す代わりにPOW[num_pow-1]を足す

		}else{

			LR_rev[i] = LR_rev[i/2]/2; //半分のインデックスの値に、2を掛ける代わりに2で割る
		}

		if(i < LR_rev[i]){
			info.push_back(Info(i,LR_rev[i]));
		}
	}
}

void calc_COMPLEX(int N){

	for(int LEN = 2,num_pow = 0; LEN <= N; LEN *= 2,num_pow++){

		MULT[num_pow].resize(LEN/2);

		MULT[num_pow][0] = COMPLEX(cos(0),sin(0));

		COMPLEX mult = COMPLEX(cos((2*M_PI)/LEN),sin((2*M_PI)/LEN));

		for(int i = 1; i < LEN/2; i++){

			if(i%2 == 1){
				MULT[num_pow][i] = MULT[num_pow][i-1]*mult;
			}else{
				MULT[num_pow][i] = MULT[num_pow-1][i/2];
			}
		}
	}
}

//離散フーリエ変換
vector<COMPLEX> DFT(vector<COMPLEX> A) {

	int N = A.size();

	/*偶数項を左に、奇数項を右に仕分けるルールで要素数1まで仕分けした場合の、
	 * 最終結果を先に作っておく(ビットが左右反転したものがその位置に来る)*/
	for(int i = 0; i < info.size(); i++){

		swap(A[info[i].left],A[info[i].right]);
	}

	COMPLEX a,add;

	for(int LEN = 2,num_pow = 0; LEN <= N; LEN *= 2,num_pow++){

		for(int start = 0; start < N; start += LEN){
			for(int i = 0; i < LEN/2; i++){
				//マージソートの容量で、配列を更新していく
				a = A[start+i];
				add = MULT[num_pow][i]*A[start+LEN/2+i];

				A[start+i] = a+add;
				A[start+LEN/2+i] = a-add;
			}
		}
	}
	return A;
}

//離散逆フーリエ変換
vector<COMPLEX> inverseDFT(vector<COMPLEX> A){

	int N = A.size();

	vector<COMPLEX> TMP = DFT(A);

	//係数を入れ替える&サイズNで各要素を割る
	vector<COMPLEX> RET(N);

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

		RET[i] = TMP[(N-i)%N];
		RET[i] = RET[i]/COMPLEX(N,0);
	}

	return RET;
}

//AとBのサイズは、大きい方に揃えておく
MATRIX convolution2D(MATRIX A,MATRIX B){

	int SIZE = A.size();

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

		if(SIZE == POW[i]){
			calc_swap_pair(SIZE,i);
					break;
		}
	}
	calc_COMPLEX(SIZE);

	MATRIX RET(SIZE,V(SIZE));

	//行についてのフーリエ変換
	for(int row = 0; row < SIZE; row++){

		A[row] = DFT(A[row]);
		B[row] = DFT(B[row]);
	}

	//列についてのフーリエ変換を行単位で処理するため、転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(A[row][col],A[col][row]);
			swap(B[row][col],B[col][row]);
		}
	}

	//列についてのフーリエ変換
	for(int row = 0; row < SIZE; row++){

		A[row] = DFT(A[row]);
		B[row] = DFT(B[row]);
	}

	//元に戻すため、再転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(A[row][col],A[col][row]);
			swap(B[row][col],B[col][row]);
		}
	}

	//ここまでの結果を計算
	for(int row = 0; row < SIZE; row++){
		for(int col = 0; col < SIZE; col++){

			RET[row][col] = A[row][col]*B[row][col];
		}
	}

	//各行をフーリエ逆変換
	for(int row = 0; row < SIZE; row++){

		RET[row] = inverseDFT(RET[row]);
	}

	//転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(RET[row][col],RET[col][row]);
		}
	}

	for(int row = 0; row < SIZE; row++){

		RET[row] = inverseDFT(RET[row]);
	}

	//元に戻すため、再転置
	for(int col = 1; col < SIZE; col++){
		for(int row = 0; row < col; row++){
			swap(RET[row][col],RET[col][row]);
		}
	}

	return RET;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i < MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N;
	scanf("%lld",&N);

	ll SIZE = 1;
	while(SIZE < 2*N)SIZE *= 2;

	MATRIX A(SIZE,V(SIZE));
	MATRIX B(SIZE,V(SIZE)); //上下左右反転

	ll tmp;
	ll first_sum = 0;

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			scanf("%lld",&tmp);
			first_sum += tmp;

			A[row][col] += tmp;
			B[(N-1)-row][(N-1)-col] += tmp;
		}
	}

	MATRIX ret = convolution2D(A,B);

	ll maximum = (N-1)*(N-1)*2;

	for(ll i = 0; i <= maximum; i++){

		ans[i] = 0;
	}

	double sum = 0;
	ll all_num = 0;

	for(ll row = 0; row <= 2*N-2; row++){
		for(ll col = 0; col <= 2*N-2; col++){

			ll dist = ((N-1)-row)*((N-1)-row)+((N-1)-col)*((N-1)-col);
			ll num = (ll)round(ret[row][col].real());

			all_num += num;

			sum += num*sqrt((double)dist);

			ans[dist] += num;
		}
		printf("\n");
	}

	all_num -= first_sum;

	printf("%.10lf\n",sum/all_num);

	int count = 0;

	ans[0] -= first_sum;

	for(ll i = 0; i <= maximum; i++){

		if(ans[i] == 0)continue;

		printf("%lld %lld\n",i,ans[i]/2);

		count++;
		if(count == 10000)break;
	}

	return 0;
}
accuracy: 0.53125
time_ms: 1080
memory_kb: 342704
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//BEGIN CUT HERE
template<typename T,typename Transformer>
struct Convolution2D{
  using Matrix = vector< vector<T> >;
  const Transformer tran;
  Convolution2D(Transformer tran):tran(tran){}

  void transpose(Matrix &as){
    int n=as.size(),m=as[0].size();
    Matrix cs(as);
    as.assign(m,vector<T>(n));
    for(int i=0;i<n;i++)
      for(int j=0;j<m;j++)
        as[j][i]=cs[i][j];
  }

  void transform(Matrix &as,bool f){
    for(int t=0;t<2;t++){
      for(auto &a:as) tran(a,f);
      transpose(as);
    }
  }

  template<typename Mul>
  Matrix multiply(Matrix as,Matrix bs,Mul mul){
    int nt=as.size()+bs.size()-1;
    int mt=as[0].size()+bs[0].size()-1;
    int n=1,m=1;
    while(n<nt) n<<=1;
    while(m<mt) m<<=1;
    as.resize(n);bs.resize(n);
    for(int i=0;i<n;i++){
      as[i].resize(m,T());
      bs[i].resize(m,T());
    }
    transform(as,0);transform(bs,0);
    for(int i=0;i<n;i++)
      for(int j=0;j<m;j++)
        as[i][j]=mul(as[i][j],bs[i][j]);
    transform(as,1);
    return as;
  }
};
//END CUT HERE

constexpr int bmds(int x){
  const int v[] = {1012924417, 985661441, 998244353,
                   897581057, 645922817};
  return v[x];
}
constexpr int brts(int x){
  const int v[] = {5, 3, 3, 3, 3};
  return v[x];
}


template<int X>
struct NTT{
  static constexpr int md = bmds(X);
  static constexpr int rt = brts(X);

  inline int add(int a,int b){
    a+=b;
    if(a>=md) a-=md;
    return a;
  }

  inline int mul(int a,int b){
    return 1LL*a*b%md;
  }

  inline int pow(int a,int b){
    int res=1;
    while(b){
      if(b&1) res=mul(res,a);
      a=mul(a,a);
      b>>=1;
    }
    return res;
  }

  inline int inv(int x){
    return pow(x,md-2);
  }

  vector<vector<int> > rts,rrts;

  void ensure_base(int n){
    if((int)rts.size()>=n) return;
    rts.resize(n);rrts.resize(n);
    for(int i=1;i<n;i<<=1){
      if(!rts[i].empty()) continue;
      int w=pow(rt,(md-1)/(i<<1));
      int rw=inv(w);
      rts[i].resize(i);rrts[i].resize(i);
      rts[i][0]=1;rrts[i][0]=1;
      for(int k=1;k<i;k++){
        rts[i][k]=mul(rts[i][k-1],w);
        rrts[i][k]=mul(rrts[i][k-1],rw);
      }
    }
  }

  void ntt(vector<int> &a,bool f,int n=-1){
    if(n==-1) n=a.size();
    assert((n&(n-1))==0);
    ensure_base(n);

    for(int i=0,j=1;j+1<n;j++){
      for(int k=n>>1;k>(i^=k);k>>=1);
      if(i>j) swap(a[i],a[j]);
    }

    for(int i=1;i<n;i<<=1){
      for(int j=0;j<n;j+=i*2){
        for(int k=0;k<i;k++){
          int z=mul(a[i+j+k],f?rrts[i][k]:rts[i][k]);
          a[i+j+k]=add(a[j+k],md-z);
          a[j+k]=add(a[j+k],z);
        }
      }
    }

    if(f){
      int tmp=inv(n);
      for(int i=0;i<n;i++) a[i]=mul(a[i],tmp);
    }
  }
};

struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;


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

//INSERT ABOVE HERE
signed main(){
  using ll = long long;
  using D = double;

  int n;
  cin>>n;

  vector< vector<int> > as(n,vector<int>(n));
  auto bs(as);

  int cnt=0;
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      cin>>as[i][j];
      bs[n-(i+1)][n-(j+1)]=as[i][j];
      cnt+=as[i][j];
    }
  }

  NTT<1> ntt1;
  NTT<2> ntt2;
  auto tran1=[&](auto &as,bool f){ntt1.ntt(as,f);};
  auto tran2=[&](auto &as,bool f){ntt2.ntt(as,f);};

  Convolution2D<int, decltype(tran1)> conv1(tran1);
  Convolution2D<int, decltype(tran2)> conv2(tran2);
  auto mul1=[&](auto a,auto b){return (ll)a*b%ntt1.md;};
  auto mul2=[&](auto a,auto b){return (ll)a*b%ntt2.md;};

  auto cs1=conv1.multiply(as,bs,mul1);
  auto cs2=conv2.multiply(as,bs,mul2);

  D dom=(D)cnt*(cnt-1)/2;
  D sum=0;
  map<ll, ll> num;
  const int S = 10000;

  auto calc=
    [&](ll a,ll b){
      const ll r01 = ntt2.inv(ntt1.md);
      b = (b - a) * r01 % ntt2.md;
      if (b < 0) b += ntt2.md;
      a = (a + b * ntt1.md);
      return a;
    };

  for(int i=0;i<(int)cs1.size();i++){
    for(int j=0;j<(int)cs1[i].size();j++){
      ll dd=(ll)(i-(n-1))*(i-(n-1))+(ll)(j-(n-1))*(j-(n-1));
      ll cc=calc(cs1[i][j],cs2[i][j]);
      if(dd==0) cc-=cnt;
      if(cc==0) continue;
      num[dd]+=cc;
      sum+=sqrt(dd)*cc;
      if((int)num.size()>S) num.erase(--num.end());
    }
  }

  cout<<sum/dom/2<<endl;
  for(auto p:num)
    cout<<p.first<<" "<<p.second/2<<"\n";
  cout<<flush;
  return 0;
}
accuracy: 1
time_ms: 2280
memory_kb: 77216
final_rank: 4

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ld = long double;
using ll = long long;
class NTT
{
    using ll = long long;
    // mod = 998244353
    const int mod = 7 * 17 * (1 << 23) + 1;

    static const int omega_max = 23;
    static const int root = 31;
    std::vector<int> omega;

    int mod_inv(ll a, ll m)
    {
        ll b = mod, u = 1, v = 0;
        while (b > 0)
        {
            ll t = a / b;
            a -= t * b;
            std::swap(a, b);
            u -= t * v;
            std::swap(u, v);
        }
        return (u % m + m) % m;
    }
    std::vector<int> fft(std::vector<int> v, bool inv)
    {
        const int n = v.size();
        // assert(n == 2冪);
        int _logn = 0;
        while ((1 << _logn) < n)
            _logn++;
        assert(1 << _logn == n);
        int ww = omega[_logn];
        if (inv)
            ww = mod_inv(ww, mod);
        for (int m = n; m >= 2; m >>= 1)
        {
            const int mh = m >> 1;
            int w = 1;
            for (int i = 0; i < mh; i++)
            {
                for (int j = i; j < n; j += m)
                {
                    const int k = j + mh;
                    int x = v[j] - v[k];
                    if (x < 0)
                        x += mod;
                    v[j] += v[k];
                    if (v[j] >= mod)
                        v[j] -= mod;
                    v[k] = (1LL * w * x) % mod;
                }
                w = (1LL * w * ww) % mod;
            }
            ww = (1LL * ww * ww) % mod;
        }

        int i = 0;
        for (int j = 1; j < n - 1; j++)
        {
            for (int k = n >> 1; k > (i ^= k); k >>= 1)
                ;
            if (j < i)
                std::swap(v[i], v[j]);
        }
        if (inv)
        {
            const int inv_n = mod_inv(n, mod);
            for (auto &x : v)
            {
                x = (1LL * x * inv_n) % mod;
            }
        }
        return v;
    }

  public:
    NTT()
    {
        omega.resize(omega_max + 1);
        int x = root;
        for (int i = omega_max; i >= 0; i--)
        {
            omega[i] = x;
            x = (1LL * x * x) % mod;
        }
    }
    std::vector<int> convolution(std::vector<int> f, std::vector<int> g)
    {
        int sz = 1;
        const int m = f.size() + g.size() - 1;
        while (sz < m)
            sz *= 2;
        f.resize(sz), g.resize(sz);
        f = this->fft(std::move(f), false);
        g = this->fft(std::move(g), false);
        for (int i = 0; i < sz; i++)
        {
            f[i] = (1LL * f[i] * g[i]) % mod;
        }
        return this->fft(std::move(f), true);
    }
};

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

    int n;
    cin >> n;
    vector<int> x(n * n * 2);
    int zero = 0;
    ld sum = 0, cnt = 0;
    NTT ntt;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            int c;
            cin >> c;
            x[2 * i * n + j] = c;
            zero += c * (c - 1) / 2;
        }
    }
    map<int, ll> count;
    if (zero > 0)
    {
        cnt = zero;
        count[0] = zero;
    }
    vector<int> y = x;
    reverse(y.begin(), y.end());
    auto ret = ntt.convolution(x, y);
    for (int i = 0; i < n; i++)
    {
        for (int j = -n + 1; j < n; j++)
        {
            if (i == 0 && j <= 0)
                continue;
            const int d = int(ret[2 * n * n - 1 + 2 * i * n + j]);
            if (d > 0)
                count[i * i + j * j] += d;
            cnt += d;
            sum += sqrt(ld(i * i + j * j)) * d;
        }
    }
    cout << fixed << setprecision(10) << sum / cnt << endl;
    int line = 0;
    for (auto p : count)
    {
        cout << p.first << " " << p.second << endl;
        line++;
        if (line >= 10000)
            break;
    }
    return 0;
}
accuracy: 1
time_ms: 5080
memory_kb: 60372
final_rank: 10

code_snippet: #include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <complex>
using namespace std;

const double Pi = acos(-1.0);
typedef long long ll;

void Read(int &p)
{
	p = 0;
	char c = getchar();
	for (; c < '0' || c > '9'; c = getchar());
	for (; c >= '0' && c <= '9'; c = getchar())p = p * 10 + c - '0';
}
struct cpx
{
	double r, i;
	cpx(){r = 0; i = 0;}
	cpx(double a, double b){r = a, i = b;}
	cpx operator + (cpx b){return cpx(r + b.r, i + b.i);}
	cpx operator - (cpx b){return cpx(r - b.r, i - b.i);}
	cpx operator * (cpx b){return cpx(r * b.r - i * b.i, r * b.i + i * b.r);}
	cpx operator *= (cpx b){return *this = *this * b;}
	cpx operator /= (double a){return *this = cpx(r / a, i / a);}
}a[1 << 22], b[1 << 22];

void DFT(cpx *A, int f, int w)
{
	for (int i = 1, j = 0; i < w; i++)
	{
		for (int d = w >> 1; j ^= d, ~j & d; d >>= 1);
		if (i < j)
			swap(A[i], A[j]);
	}
	for (int i = 1; i < w; i <<= 1)
	{
		cpx wn(cos(Pi / i), f * sin(Pi / i));
		for (int j = 0; j < w; j += i << 1)
		{
			int k = j + i;
			cpx w1(1, 0);
			for (int l = 0; l < i; l++)
			{
				cpx x = A[j + l], y = w1 * A[k + l];
				A[j + l] = x + y;
				A[k + l] = x - y;
				w1 *= wn;
			}
		}
	}
	if (f == -1)
		for (int i = 0; i < w; i++)
			A[i] /= w;
}


int n, sum;
int C[1 << 10][1 << 10];
ll ans[2100000];

int main()
{
    scanf("%d", &n);
    int w = 1, setlen = (n - 1) * (n * 2 + 1);
    while (w <= setlen * 2)w <<= 1;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		{
			Read(C[i][j]);
			sum += C[i][j];
			ans[0] += C[i][j] * (C[i][j] - 1) / 2;
            int id = i * 2 * n + j;
			a[id].r = C[i][j];
			b[setlen - id].r = C[i][j];
		}
	DFT(a, 1, w), DFT(b, 1, w);
	for (int i = 0; i < w; i++)
		a[i] = a[i] * b[i];
	DFT(a, -1, w);
    double ans1 = 0;
    for (int i = 1; i <= setlen; i++)
	{
		ll t = (ll)(a[setlen + i].r + 0.3);
		if(!t) continue;
        int dx = ((i / n) + 1) >> 1;
        int dy = abs(i - dx * n * 2);
        ans1 += sqrt((double)dx * dx + (double)dy * dy) * t;
        ans[dx*dx+dy*dy] += t;
    }

    ans1 /= (double)sum * (sum - 1) / 2;
    printf("%.10f\n", ans1);

    int num = 0;

    int top = (n - 1) * (n - 1) * 2;
    for(int i = 0; i <= top && num < 10000; i++) if(ans[i]) {
        printf("%d %lld\n", i, ans[i]);
        num++;
    }

    return 0;
}
accuracy: 1
time_ms: 1080
memory_kb: 154160
final_rank: 3