Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // main.cpp
- // solve
- //
- // Created by Ahmed on 11/16/16.
- // Copyright © 2016 Abdellah. All rights reserved.
- //
- #include<set>
- #include<map>
- #include <unordered_map>
- #include <unordered_set>
- #include<list>
- #include<iomanip>
- #include<cmath>
- #include<string>
- #include<vector>
- #include<queue>
- #include<stack>
- #include<complex>
- #include<sstream>
- #include<iostream>
- #include<fstream>
- #include<algorithm>
- #include<numeric>
- #include<utility>
- #include<functional>
- #include<stdio.h>
- #include<assert.h>
- #include<memory.h>
- #include<bitset>
- #include<math.h>
- #include <strings.h>
- #define f first
- #define s second
- #define pb push_back
- #define sz(a) (int)(a).size()
- #define lp(i,a,n) for(int (i)=(a);(i)<=(int)(n);(i)++)
- #define lpd(i,n,a) for(int (i)=(n);(i)>=(a);--(i))
- #define mp make_pair
- #define clr(a,b) memset(a,b,sizeof a)
- #define all(v) (v).begin(),(v).end()
- #define mod 1000000007
- #define eps 1e-6
- #define infi 1000000002
- #define infll 4000000000000000005ll
- #define MX 1000000
- #define X real()
- #define Y imag()
- #define polar(r,t) ((r)* exp(point(0,(t))))
- #define length(a) hypot( (a).X , (a).Y )
- #define angle(a) atan2( (a).Y , (a).X )
- #define vec(a,b) ( (b) - (a) )
- #define dot(a,b) (conj(a)*(b)).X
- #define cross(a,b) (conj(a)*(b)).Y
- #define lengthsqr(a) dot(a,a)
- #define reflect(V,M) (conj((V)/(M)) * (M))
- #define normalize(a) ((a)/length(a))
- #define ccw(a,b,c) cross(vec(a,b) , vec(a,c)) > -eps
- #define cosRule(a,b,c) (acos(((a)*(a)+(b)*(b)-(c)*(c))/(2*(a)*(b))))
- #define cosDot(a,b) (acos(dot(a,b)/length(a)/length(b)))
- #define EQ(a,b) (fabs((a) - (b)) <= eps) /* equal to */
- #define NE(a,b) (fabs((a) - (b)) > eps) /* not equal to */
- #define LT(a,b) ((a) < (b) - eps) /* less than */
- #define GT(a,b) ((a) > (b) + eps) /* greater than */
- #define LE(a,b) ((a) <= (b) + eps) /* less than or equal to */
- #define GE(a,b) ((a) >= (b) - eps) /* greater than or equal to */
- #define mod1 100050001
- #define mod2 100030001
- #define base1 37
- #define base2 31
- #define que priority_queue<pair<int,int>, vector<pair<int,int>> , greater<pair<int,int> > >
- #define rotate(v,t) ((v)*exp(point(0,t)))
- #define rotateabout(v,t,a) (rotate(vec(a,v),t)+(a))
- #define PI atan(1)*4
- using namespace std;
- typedef long long ll;
- typedef pair<int, int> pii;
- typedef pair<double,double> pdd;
- typedef pair<ll, ll> pll;
- typedef vector<int> vi;
- typedef vector<ll> vll;
- typedef vector<vi> vvi;
- typedef set<int> si;
- typedef map<int, int> mii;
- typedef map<ll, ll> mll;
- typedef unordered_map<ll, ll> umll;
- typedef complex<long double> point;
- typedef pair<point, point> line;
- typedef pair<double , point> Circle;
- const int N = 50002;
- vi tree[N], centroidTree[N];
- bool centroidMarked[N], vis[N], color[N];
- int n,m,siz[N], centroidParent[N];
- void DFS(int node, int* n)
- {
- vis[node] = true;
- *n += 1;
- siz[node] = 1;
- for(int ch:tree[node])
- if (!vis[ch] && !centroidMarked[ch])
- {
- DFS(ch, n);
- siz[node]+=siz[ch];
- }
- }
- int getCentroid(int node, int n)
- {
- bool is_centroid = true;
- vis[node] = true;
- int heaviest_child = 0;
- for(int ch:tree[node])
- if (!vis[ch] && !centroidMarked[ch])
- {
- if (siz[ch]>n/2)
- is_centroid=false;
- if (heaviest_child==0 || siz[ch]>siz[heaviest_child])
- heaviest_child = ch;
- }
- if (is_centroid && n-siz[node]<=n/2)
- return node;
- return getCentroid(heaviest_child, n);
- }
- int getCentroid(int src)
- {
- clr(siz,0), clr(vis, false);
- int n = 0;
- DFS(src, &n);
- clr(vis, false);
- int centroid = getCentroid(src, n);
- centroidMarked[centroid]=true;
- return centroid;
- }
- int decomposeTree(int root)
- {
- int cend_tree = getCentroid(root);
- // printf("%d ", cend_tree);
- for(int ch:tree[cend_tree])
- {
- if (!centroidMarked[ch])
- {
- int cend_subtree = decomposeTree(ch);
- centroidTree[cend_tree].push_back(cend_subtree);
- centroidTree[cend_subtree].push_back(cend_tree);
- centroidParent[cend_subtree] = cend_tree;
- }
- }
- return cend_tree;
- }
- int eTour[2*N][22],sTime[N],inv[2*N],level[N],lg[2*N],elen;
- void dfs(int node,int p,int depth) {
- sTime[node] = ++elen;
- inv[elen] = node;
- eTour[elen][0] = sTime[node];
- level[node] = depth;
- for(int ch:tree[node])
- if(ch != p) dfs(ch, node,depth+1), eTour[++elen][0] = sTime[node], inv[elen] = node;
- }
- void build() {
- for(int i=0;(1<<i) <= 2*n ; ++i) lg[1<<i] = i;
- lp(i, 1, 2*n-1) if(!lg[i]) lg[i] = lg[i-1];
- lp(i, 0, 2*n) lp(j, 0, 20) eTour[i][j] = infi;
- dfs(1, -1,1);
- for(int j=1; (1<<j) <= elen ; ++j) lp(i, 1, elen) if(i+(1<<j)-1 <= elen)
- eTour[i][j] = min(eTour[i][j-1], eTour[i+(1<<(j-1))][j-1]);
- }
- int LCA(int p,int q) {
- if(sTime[p] > sTime[q]) swap(q, p);
- int l = sTime[p], r = sTime[q];
- int shift = lg[r - l + 1];
- return inv[min(eTour[l][shift], eTour[r-(1<<shift)+1][shift])];
- }
- int dist(int u,int v) {
- return level[u] + level[v] - 2*level[LCA(u, v)];
- }
- vi primes;
- void init () {
- vector<bool> isPrime(N, true);
- isPrime[0] = isPrime[1] = false;
- lp(i, 2, N-1) if(isPrime[i]) {
- primes.pb(i);
- for(ll j = 1ll*i*i ; j < N ; j += i)
- isPrime[j] = false;
- }
- }
- unordered_map<int, int> dists[N];
- void calc_dists() {
- lp(i, 1, n) {
- int p = i;
- while (p != -1) ++dists[p][dist(i, p)] , p = centroidParent[p];
- }
- }
- ll solve() {
- ll ret = 0;
- lp(i, 1, n) {
- int par = i, prev = -1;
- while (par != -1) {
- int d = dist(i, par);
- for(int p:primes) if(dists[par].count(p-d)) {
- ret += dists[par][p-d];
- if(prev != -1 && dists[prev].count(p-d-1))
- ret -= dists[prev][p-d-1];
- }
- prev = par;
- par = centroidParent[par];
- }
- }
- return ret;
- }
- int main() {
- scanf("%d",&n);
- lp(i, 2, n) {
- int a,b;
- scanf("%d%d",&a,&b);
- tree[a].pb(b) , tree[b].pb(a);
- }
- build() , init();
- clr(centroidParent, -1);
- decomposeTree(1);
- calc_dists();
- long double ans = solve();
- ans /= n, ans /= (n-1);
- printf("%Lf\n",ans);
- return 0;
- }
- /*
- 4
- 1 2
- 2 3
- 2 4
- */
- //freopen("output.txt","w",stdout);
- //freopen("input.txt","r",stdin);
- //ios::sync_with_stdio(0);cin.tie(0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement