tyvj1953 Normal
正解:点分治+$FFT$。
很想吐槽一下$bzoj$,为什么搬了别的$oj$的题还设成权限题。。
首先我们考虑期望的线性性,即考虑每个点的贡献。
显然每个点的贡献就是它在点分树上的深度,所以我们进一步考虑哪些点在它到根的路径上。
我们考虑每一条路径的贡献,显然对于一条路径$(x,y)$,当且仅当$x$是路径上最浅的点时会对$y$有$1$的贡献。
那么这条路径$x$深度最浅的概率,实际上就是$\frac{1}{len(x,y)}$,因为每个点作为深度最浅的点的概率相等。
所以我们统计每一种长度的路径个数就行了,这个用$FFT$即可解决。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define N (1000005) 6 7 using namespace std; 8 9 struct edge{ int nt,to; }g[N]; 10 struct C{ 11 double x,y; 12 il C operator + (const C &a) const{ 13 return (C){x+a.x,y+a.y}; 14 } 15 il C operator - (const C &a) const{ 16 return (C){x-a.x,y-a.y}; 17 } 18 il C operator * (const C &a) const{ 19 return (C){x*a.x-y*a.y,x*a.y+y*a.x}; 20 } 21 }a[N]; 22 23 const double pi=acos(-1.0); 24 25 int head[N],vis[N],dis[N],son[N],sz[N],rev[N],n,num,len,Max; 26 double ans[N],Ans; 27 28 il int gi(){ 29 RG int x=0,q=1; RG char ch=getchar(); 30 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 31 if (ch=='-') q=-1,ch=getchar(); 32 while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); 33 return q*x; 34 } 35 36 il void insert(RG int from,RG int to){ 37 g[++num]=(edge){head[from],to},head[from]=num; return; 38 } 39 40 il void fft(C *a,RG int n,RG int f){ 41 for (RG int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]); 42 for (RG int i=1;i<n;i<<=1){ 43 C wn=(C){cos(pi/i),sin(f*pi/i)}; 44 for (RG int j=0;j<n;j+=i<<1){ 45 C w=(C){1,0},x,y; 46 for (RG int k=0;k<i;++k,w=w*wn){ 47 x=a[j+k],y=w*a[j+k+i]; 48 a[j+k]=x+y,a[j+k+i]=x-y; 49 } 50 } 51 } 52 if (f==-1) for (RG int i=0;i<len;++i) a[i].x/=n; return; 53 } 54 55 il void getrt(RG int x,RG int p,RG int &rt){ 56 son[x]=0,sz[x]=1; 57 for (RG int i=head[x],v;i;i=g[i].nt){ 58 v=g[i].to; if (v==p || vis[v]) continue; 59 getrt(v,x,rt),sz[x]+=sz[v],son[x]=max(son[x],sz[v]); 60 } 61 son[x]=max(son[x],son[0]-sz[x]); 62 if (son[rt]>=son[x]) rt=x; return; 63 } 64 65 il void getdis(RG int x,RG int p){ 66 sz[x]=1,++a[dis[x]].x,Max=max(Max,dis[x]); 67 for (RG int i=head[x],v;i;i=g[i].nt){ 68 v=g[i].to; if (v==p || vis[v]) continue; 69 dis[v]=dis[x]+1,getdis(v,x),sz[x]+=sz[v]; 70 } 71 return; 72 } 73 74 il void calc(RG int rt,RG int lim,RG int fg){ 75 Max=0,dis[rt]=lim,getdis(rt,0); RG int lg=0; 76 for (len=1;len<=(Max<<1);len<<=1) ++lg; 77 for (RG int i=0;i<len;++i) rev[i]=rev[i>>1]>>1|((i&1)<<(lg-1)); 78 fft(a,len,1); for (RG int i=0;i<len;++i) a[i]=a[i]*a[i]; fft(a,len,-1); 79 for (RG int i=0;i<len;++i) ans[i]+=(ll)(a[i].x+0.5)*fg,a[i]=(C){0,0}; return; 80 } 81 82 il void solve(RG int x,RG int S){ 83 RG int rt=0; son[0]=S,getrt(x,0,rt); 84 vis[rt]=1,calc(rt,0,1); 85 for (RG int i=head[rt];i;i=g[i].nt) 86 if (!vis[g[i].to]) calc(g[i].to,1,-1); 87 for (RG int i=head[rt];i;i=g[i].nt) 88 if (!vis[g[i].to]) solve(g[i].to,sz[g[i].to]); 89 return; 90 } 91 92 int main(){ 93 #ifndef ONLINE_JUDGE 94 freopen("normal.in","r",stdin); 95 freopen("normal.out","w",stdout); 96 #endif 97 n=gi(); 98 for (RG int i=1,u,v;i<n;++i) 99 u=gi()+1,v=gi()+1,insert(u,v),insert(v,u); 100 solve(1,n); 101 for (RG int i=0;i<n;++i) Ans+=1.0*ans[i]/(i+1); 102 printf("%0.4lf\n",Ans); return 0; 103 }