
题目链接:
询问这个简单环的期望。考虑将这个环拆成两部分。
令${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 else
111 {
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("%.9lfn",ans);
116 }
117 return 0;
118 }
转载于:.html
本文发布于:2024-02-04 05:06:34,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170699741252324.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
| 留言与评论(共有 0 条评论) |