首页 > 代码库 > Codeforces 629 E. Famil Door and Roads

Codeforces 629 E. Famil Door and Roads

题目链接:http://codeforces.com/problemset/problem/629/E


 

询问这个简单环的期望。考虑将这个环拆成两部分。

令${deep[x]>=deep[y]}$,${size[x]}$表示以$x$为根的子树大小,${sdown[x]}$示以$x$为根的子树的所有节点到$x$的距离和,${sall[x]}$所有点到$x$的距离和。${ne}$表示从${y-->x}$路径上${y}$的儿子。

1.${dis(x,y)}$这是一个环肯定要经过的,算入答案。

2.分情况考虑:

  若是${lca(x,y)!=y}$,会产生${\frac{sdown[x]}{size[x]}+\frac{sdown[y]}{size[y]}}$的贡献。

  若是${lca(x,y)=y}$,会产生${\frac{sdown[x]}{size[x]}+\frac{sdall[y]-sdown[ne]-size[ne]}{n-size[ne]}}$的贡献。

  1 #include<iostream>  2 #include<cstdio>  3 #include<algorithm>  4 #include<vector>  5 #include<cstdlib>  6 #include<cmath>  7 #include<cstring>  8 using namespace std;  9 #define maxn 200010 10 #define llg long long  11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,T; 13 llg sall[maxn],sdown[maxn],deep[maxn],f[maxn][21],size[maxn]; 14 vector<llg>a[maxn]; 15  16 inline llg getint() 17 { 18        llg w=0,q=0; char c=getchar(); 19        while((c<0 || c>9) && c!=-) c=getchar(); if(c==-) q=1,c=getchar();  20        while (c>=0 && c<=9) w=w*10+c-0, c=getchar(); return q ? -w : w; 21 } 22  23 void dfs1(llg x,llg fa) 24 { 25     llg w=a[x].size(),v; 26     deep[x]=deep[fa]+1; f[x][0]=fa; 27     size[x]=1; 28     for (llg i=0;i<w;i++) 29     { 30         v=a[x][i]; 31         if (v==fa) continue; 32         dfs1(v,x); 33         size[x]+=size[v]; 34         sdown[x]+=sdown[v]+size[v]; 35     } 36 } 37  38 void dfs2(llg x,llg fa) 39 { 40     llg w=a[x].size(),v; 41     for (llg i=0;i<w;i++) 42     { 43         v=a[x][i]; 44         if (v==fa) continue; 45         sall[v]=sall[x]+n-2*size[v]; 46         dfs2(v,x); 47     } 48 } 49  50 void init() 51 { 52     llg x,y; 53     cin>>n>>T; 54     for (llg i=1;i<n;i++) 55     { 56         x=getint(),y=getint(); 57         a[x].push_back(y),a[y].push_back(x); 58     } 59     deep[1]=1; 60     dfs1(1,0); 61     sall[1]=sdown[1]; 62     dfs2(1,0); 63     for (llg j=1;j<=20;j++) 64         for (llg i=1;i<=n;i++) 65             f[i][j]=f[f[i][j-1]][j-1]; 66 } 67  68 llg find(llg x,llg y) 69 { 70     for (llg i=20;i>=0;i--) 71         if (deep[f[x][i]]>=deep[y]) 72             x=f[x][i]; 73     if (x==y) return x; 74     for (llg i=20;i>=0;i--) 75         if (f[x][i]!=f[y][i]) 76             x=f[x][i],y=f[y][i]; 77     return f[x][0]; 78 } 79  80 llg dis(llg x,llg y)  81 { 82     return deep[x]+deep[y]-deep[find(x,y)]*2; 83 } 84  85 llg up(llg x,llg res) 86 { 87     for (llg i=20;i>=0;i--) 88         if (res>=(1<<i)) 89         { 90             x=f[x][i]; 91             res-=(1<<i); 92         } 93     return x; 94 } 95  96 int main() 97 { 98     yyj("tree"); 99     init();100     while (T--)101     {102         llg x,y;103         x=getint(),y=getint();104         if (deep[x]<deep[y]) swap(x,y);105         double ans=dis(x,y)+1;106         if (find(x,y)!=y)107         {108             ans+=(double)sdown[x]/(double)size[x]+(double)sdown[y]/(double)size[y];109         }110         else111         {112             llg ne=up(x,deep[x]-deep[y]-1);113             ans+=(double)sdown[x]/(double)size[x]+(double)(sall[y]-sdown[ne]-size[ne])/(double)(n-size[ne]);114         }115         printf("%.9lf\n",ans);116     }117     return 0;118 }

 


 

Codeforces 629 E. Famil Door and Roads