- #include <algorithm>
- #include <iostream>
- #include <iomanip>
- #include <cstring>
- #include <cstdlib>
- #include <complex>
- #include <string>
- #include <vector>
- #include <cstdio>
- #include <cmath>
- //#include <ctime>
- #include <map>
- using namespace std;
-
- // FFT on complex filed. (You can also use FFT on finite field.)
- complex <double> x[1<<20];
- complex <double> y[1<<20];
- complex <double> r[1<<20];
-
- namespace Fourier
- {
- // n must be 2^k
- complex <double> t[1<<20];
- void FFT(complex <double> *array, int n, double pi = M_PI)
- {
- for(int step = n>>1; step >= 1; step >>= 1)
- {
- complex <double> w(cos(2 * pi * step / n), sin(2 * pi * step / n));
- for(int start = 0; start < step; start ++)
- {
- complex <double> factor(1, 0);
- int z = 0;
- for(int i = start; i < n; i += step << 1)
- {
- array[i+step] *= factor;
- array[i] += array[i+step];
- array[i+step] = array[i] - array[i+step] - array[i+step];
- factor *= w;
- t[z] = array[i];
- t[z+n/step/2] = array[i+step];
- z ++;
- }
- z = 0;
- for(int i = start; i < n; i += step)
- array[i] = t[z++];
- }
- }
- for(int i = 0; i < n; i++)
- array[i] *= complex <double> (1/sqrt(n), 0);
- }
-
- void IFFT(complex <double> *array, int n)
- {
- FFT(array, n, -M_PI);
- }
-
- void cyclic_convolution(complex <double> *A, complex <double> *B, complex <double> *result, int n)
- {
- FFT(A, n);
- FFT(B, n);
- for(int i = 0; i < n; i++)
- result[i] = A[i] * B[i];
- IFFT(result, n);
- for(int i = 0; i < n; i++)
- result[i] *= complex <double> (sqrt(n), 0);
- }
- }
-
- int n;
- const int MAXN = 200000;
- const int MAXDEPTH = 20;
- vector <int> e[MAXN];
- int cntNodes[MAXN];
- int minValue, center;
-
- vector <int> cache[MAXDEPTH][4];
- int cache_ans[MAXDEPTH][4][MAXN];
- int ans[MAXN];
- int temp1[MAXN];
- int temp2[MAXN];
- int temp3[MAXN];
- int temp[MAXN];
- int saveN[MAXDEPTH];
-
- // find the minimal n such that 2**n > x
- int minimalPow2(int x)
- {
- int ret = 0;
- int t = 1;
- while(t < x)
- {
- ret ++;
- t = t + t;
- }
- return ret;
- }
-
- // use dfs to find the center of a tree
- int dfs(int cur, int from, int d, int n, bool special = false, int depth = -1)
- {
- if(special)
- cache_ans[depth][0][d] ++;
- cntNodes[cur] = 1;
- int maxSubTree = 0, cnt = 0;
- for(int i = 0; i < e[cur].size(); i++)
- if(e[cur][i] != from)
- {
-
- int t = dfs(e[cur][i], cur, d+1, n, special, depth);
- cntNodes[cur] += cntNodes[e[cur][i]];
- cnt += t;
- maxSubTree = max(maxSubTree, t);
- }
- maxSubTree = max(maxSubTree, n-1-cnt);
- if(n > 0 && maxSubTree < minValue)
- {
- center = cur;
- minValue = maxSubTree;
- }
- return cnt + 1;
- }
-
- int totNodes;
-
- int findCenter(int root, int depth)
- {
- int n = dfs(root, -1, 0, 0, true, depth);
- minValue = 100000000;
- totNodes = dfs(root, -1, 0, n, false, depth);
- dfs(center, -1, 0, n, false, depth);
- return center;
- }
-
- // A[i]: number of nodes have a distance i from subtree A
- // B[i]: number of nodes have a distance i from subtree B
- // Update all pathes between subtree A and subtree B
- void calcPair(int *A, int *B, int N)
- {
- for(int i = 0; i < (1<<N); i++)
- {
- x[i] = complex <double> (A[i], 0);
- y[i] = complex <double> (B[i], 0);
- }
- Fourier :: cyclic_convolution(x, y, r, 1<<N);
-
- for(int i = 1; i < (1<<N); i++)
- ans[i] += (long long)(r[i].real() + 0.5);
- }
-
- void solve(int root, int depth, int reqN)
- {
- for(int i = 0; i < (1<<reqN); i++)
- {
- cache_ans[depth][0][i] = 0;
- cache_ans[depth][1][i] = 0;
- cache_ans[depth][2][i] = 0;
- cache_ans[depth][3][i] = 0;
- }
- int center = findCenter(root, depth);
- int totalNodes = cntNodes[center];
-
- cache_ans[depth][0][0] = 1;
- if(totalNodes <= 2)
- {
- if(totalNodes == 2)
- {
- cache_ans[depth][0][1] = 1;
- ans[1] ++;
- }
- return;
- }
- cache[depth][0] = e[center];
- cache[depth][1].clear(), cache[depth][2].clear(), cache[depth][3].clear();
- int cnt = 1;
-
- // The subtree will be grouped into 3 parts, each one has a size no more than N/2.
- for(int i = 0; i < e[center].size(); i++)
- {
- int before = cnt;
- int after = cnt + cntNodes[e[center][i]];
- cnt = after;
- if(after <= totalNodes / 2)
- cache[depth][1].push_back(e[center][i]);
- else if(before <= totalNodes / 2)
- cache[depth][2].push_back(e[center][i]);
- else
- cache[depth][3].push_back(e[center][i]);
- }
- int N = minimalPow2(totalNodes);
- N = max(N, 2);
-
- e[center] = cache[depth][1];
- solve(center, depth + 1, N);
- for(int i = 1; i < (1<<N); i++)
- cache_ans[depth][1][i] = cache_ans[depth+1][0][i];
-
- e[center] = cache[depth][2];
- solve(center, depth + 1, N);
- for(int i = 1; i < (1<<N); i++)
- cache_ans[depth][2][i] = cache_ans[depth+1][0][i];
-
- e[center] = cache[depth][3];
- solve(center, depth + 1, N);
- for(int i = 1; i < (1<<N); i++)
- cache_ans[depth][3][i] = cache_ans[depth+1][0][i];
-
- e[center] = cache[depth][0];
-
- for(int i = 0; i < (1<<reqN); i++)
- {
- temp1[i] = cache_ans[depth][1][i];
- temp2[i] = cache_ans[depth][2][i];
- temp3[i] = cache_ans[depth][3][i];
- }
- calcPair(temp1, temp2, reqN);
- calcPair(temp1, temp3, reqN);
- calcPair(temp2, temp3, reqN);
- }
-
- bool isPrime[1000001];
-
-
- int MAIN()
- {
- memset(isPrime, true, sizeof(isPrime));
- isPrime[0] = isPrime[1] = false;
- for(int i = 2; i <= 1000000; i++)
- if(isPrime[i])
- for(int j = i+i; j <= 1000000; j+=i)
- isPrime[j] = false;
-
- memset(ans, 0, sizeof(ans));
- memset(cache_ans, 0, sizeof(cache_ans));
- cin >> n;
- for(int i = 1; i < n; i++)
- {
- int a, b;
- cin >> a >> b;
- e[a].push_back(b);
- e[b].push_back(a);
- }
- solve(1, 0, minimalPow2(n));
-
- double total = 0, sum = 0;
- for(int i = 1; i <= n; i++)
- {
- total += ans[i];
- if(isPrime[i])
- sum += ans[i];
- }
- cout << sum / total << endl;
- return 0;
- }
-
-
- int main()
- {
- //srand((unsigned)time(NULL));
- #ifdef LOCAL_TEST
- freopen("in.txt", "r", stdin);
- freopen("out.txt", "w", stdout);
- #endif
- ios :: sync_with_stdio(false);
- cout << fixed << setprecision(16);
- return MAIN();
- }