1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #include <bits/stdc++.h> #define MAXN 500005 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^'0'); ch=getchar(); } return x*f; } const double PI=acos(-1.0); struct Complex{ double x,y; }; inline Complex operator + (const Complex &A,const Complex &B){ return Complex{A.x+B.x,A.y+B.y}; } inline Complex operator - (const Complex &A,const Complex &B){ return Complex{A.x-B.x,A.y-B.y}; } inline Complex operator * (const Complex &A,const Complex &B){ return Complex{A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x}; } Complex A[MAXN]; int r[MAXN]; inline void FFT(Complex *A,int n,int type){ for (register int i=0;i<n;++i) if (i<r[i]) swap(A[i],A[r[i]]); for (register int i=1;i<n;i<<=1){ int R=i<<1; Complex Wn=Complex{cos(2*PI/R),type*sin(2*PI/R)}; for (register int j=0;j<n;j+=R){ Complex w=Complex{1,0}; for (register int k=0;k<i;++k,w=w*Wn){ Complex x=A[j+k],y=w*A[i+j+k]; A[j+k]=x+y,A[i+j+k]=x-y; } } } if (type==-1){ for (register int i=0;i<n;++i) A[i].x/=(double)n; } } int d[MAXN],ret[MAXN],ans[MAXN],sz; inline void Mul(int f){ int m=1,L=0; while (m<=2*sz) m<<=1,L++; for (register int i=0;i<=m;++i){ r[i]=r[i>>1]>>1|((i&1)<<(L-1)); } FFT(A,m,1); for (register int i=0;i<m;++i) A[i]=A[i]*A[i]; FFT(A,m,-1); for (register int i=0;i<=sz*2;++i) ans[i]+=f*(int)(A[i].x+0.5); for (register int i=0;i<=m;++i) A[i].x=0,A[i].y=0; }
vector<int>G[MAXN]; inline void AddEdge(int u,int v){ G[u].push_back(v); } int dp[MAXN],max_dp[MAXN],vis[MAXN],tot,root; inline void InitDP(int u,int father){ dp[u]=1,max_dp[u]=0; for (register int i=0;i<(int)G[u].size();++i){ int v=G[u][i]; if (v!=father&&!vis[v]){ InitDP(v,u); dp[u]+=dp[v]; max_dp[u]=max(max_dp[u],dp[v]); } } max_dp[u]=max(max_dp[u],tot-dp[u]); if (max_dp[root]>max_dp[u]) root=u; } int n; inline int GetRoot(int u,int s){ tot=s,root=0; InitDP(u,0); return root; } inline void InitDep(int u,int father,int dep){ sz=max(sz,dep); A[dep].x++; for (register int i=0;i<(int)G[u].size();++i){ int v=G[u][i]; if (v!=father&&!vis[v]){ InitDep(v,u,dep+1); } } } inline void Calc(int u,int f){ sz=0; InitDep(u,0,f==-1?1:0); Mul(f); } inline void dfs(int u){ vis[u]=true; Calc(u,1); for (register int i=0;i<(int)G[u].size();++i){ int v=G[u][i]; if (!vis[v]){ Calc(v,-1); dfs(GetRoot(v,dp[v])); } } } int main(){ n=read(); max_dp[0]=n; for (register int i=1;i<n;++i){ int u=read()+1,v=read()+1; AddEdge(u,v); AddEdge(v,u); } dfs(GetRoot(1,n)); double ret=0; for (register int i=0;i<n;++i){ ret+=(double)ans[i]/(i+1); } printf("%.4lf\n",ret); }
|