根据期望的线性性,答案就是 \(\sum\) 每个连通块出现次数的期望

而每个连通块次数的期望就是 \(\sum\) 连通块的根与每个点连通次数的期望

也就是对于一条路径 \((i,j)\),设 \(i\) 为根,那么 \(i\) 必须是这条路径第一个被选择的点,概率为 \(\frac{1}{dis(i,j)}\),其中 \(dis(i,j)\) 表示 \((i,j)\) 上的点数

那么只要统计不同的 \(dis(i,j)\) 的个数即可

直接点分治+\(FFT\)

# include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn(1 << 18);
const int mod(998244353); inline void Inc(int &x, int y) {
x = x + y >= mod ? x + y - mod : x + y;
} inline void Dec(int &x, int y) {
x = x - y < 0 ? x - y + mod : x - y;
} inline int Add(int x, int y) {
return x + y >= mod ? x + y - mod : x + y;
} inline int Sub(int x, int y) {
return x - y < 0 ? x - y + mod : x - y;
} inline int Pow(ll x, int y) {
register ll ret = 1;
for (; y; y >>= 1, x = x * x % mod)
if (y & 1) ret = ret * x % mod;
return ret;
} int w[2][maxn], a[maxn], b[maxn], len, l, r[maxn]; inline void Init(int n) {
int i, x, y;
for (l = 0, len = 1; len < n; len <<= 1) ++l;
for (i = 0; i < len; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
x = Pow(3, (mod - 1) / len), y = Pow(x, mod - 2), w[0][0] = w[1][0] = 1;
for (i = 1; i < len; ++i) w[0][i] = (ll)w[0][i - 1] * x % mod, w[1][i] = (ll)w[1][i - 1] * y % mod;
for (i = 0; i < len; ++i) a[i] = b[i] = 0;
} inline void DFT(int *p, int opt) {
int i, j, k, x, y, t;
for (i = 0; i < len; ++i) if (i < r[i]) swap(p[i], p[r[i]]);
for (i = 1; i < len; i <<= 1)
for (j = 0, t = i << 1; j < len; j += t)
for (k = 0; k < i; ++k) {
x = p[j + k], y = (ll)w[opt == -1][len / t * k] * p[j + k + i] % mod;
p[j + k] = Add(x, y), p[j + k + i] = Sub(x, y);
}
if (opt == -1) for (i = 0, t = Pow(len, mod - 2); i < len; ++i) p[i] = (ll)p[i] * t % mod;
} int n, first[maxn], cnt, cur[maxn], size[maxn], mx[maxn], vis[maxn], rt, sz, deep[maxn], mxd;
long double ans; struct Edge {
int to, next;
} edge[maxn << 1]; inline void AddEdge(int u, int v) {
edge[cnt] = (Edge){v, first[u]}, first[u] = cnt++;
edge[cnt] = (Edge){u, first[v]}, first[v] = cnt++;
} void Getroot(int u, int ff) {
int e, v;
size[u] = 1, mx[u] = 0;
for (e = first[u]; ~e; e = edge[e].next)
if ((v = edge[e].to) != ff && !vis[v]) {
Getroot(v, u);
size[u] += size[v];
mx[u] = max(mx[u], size[v]);
}
mx[u] = max(mx[u], sz - size[u]);
if (mx[u] < mx[rt]) rt = u;
} void Getdeep(int u, int ff, int d) {
int e, v;
++deep[d], mxd = max(mxd, d);
for (e = first[u]; ~e; e = edge[e].next)
if ((v = edge[e].to) != ff && !vis[v]) Getdeep(v, u, d + 1);
} void Solve(int u) {
int e, v, i, len1, len2;
mxd = 0, Getdeep(u, 0, 0), vis[u] = 1;
Init((mxd << 1) + 1), len1 = mxd << 1;
for (i = 0; i <= mxd; ++i) a[i] = deep[i], deep[i] = 0;
DFT(a, 1), len2 = len;
for (i = 0; i < len2; ++i) a[i] = (ll)a[i] * a[i] % mod;
DFT(a, -1);
for (i = 0; i <= len1; ++i) Inc(cur[i + 1], a[i]);
for (e = first[u]; ~e; e = edge[e].next)
if (!vis[v = edge[e].to]) {
mxd = 0, Getdeep(v, u, 1), Init(mxd << 1 | 1), len1 = mxd << 1;
for (i = 0; i <= mxd; ++i) b[i] = deep[i], deep[i] = 0;
DFT(b, 1);
for (i = 0; i < len; ++i) b[i] = (ll)b[i] * b[i] % mod;
DFT(b, -1);
for (i = 0; i <= len1; ++i) Dec(cur[i + 1], b[i]);
}
for (e = first[u]; ~e; e = edge[e].next)
if (!vis[v = edge[e].to]) {
rt = 0, sz = size[v];
Getroot(v, u), Solve(rt);
}
} int main() {
int i, j, k, u, v;
memset(first, -1, sizeof(first));
scanf("%d", &n);
for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), AddEdge(u + 1, v + 1);
sz = n, mx[0] = n + 1, Getroot(1, 0), Solve(rt);
for (i = 1; i <= n; ++i) if (cur[i]) ans += 1.0 * cur[i] / (1.0 * i);
printf("%.4Lf\n", ans);
return 0;
}

BZOJ3451:Tyvj1953 Normal的更多相关文章

  1. 【BZOJ3451】Tyvj1953 Normal 点分治+FFT+期望

    [BZOJ3451]Tyvj1953 Normal Description 某天WJMZBMR学习了一个神奇的算法:树的点分治!这个算法的核心是这样的:消耗时间=0Solve(树 a) 消耗时间 += ...

  2. 【bzoj3451】Tyvj1953 Normal 期望+树的点分治+FFT

    题目描述 给你一棵 $n$ 个点的树,对这棵树进行随机点分治,每次随机一个点作为分治中心.定义消耗时间为每层分治的子树大小之和,求消耗时间的期望. 输入 第一行一个整数n,表示树的大小接下来n-1行每 ...

  3. 【BZOJ3451】Tyvj1953 Normal - 点分治+FFT

    题目来源:NOI2019模拟测试赛(七) 非原题面,题意有略微区别 题意: 吐槽: 心态崩了. 好不容易场上想出一题正解,写了三个小时结果写了个假的点分治,卡成$O(n^2)$ 我退役吧. 题解: 原 ...

  4. BZOJ3451: Tyvj1953 Normal

    题解: 好神的一道题.蒟蒻只能膜拜题解. 考虑a对b的贡献,如果a是a-b路径上第一个删除的点,那么给b贡献1. 所以转化之后就是求sigma(1/dist(i,j)),orz!!! 如果不是分母的话 ...

  5. bzoj 3451: Tyvj1953 Normal [fft 点分治 期望]

    3451: Tyvj1953 Normal 题意: N 个点的树,点分治时等概率地随机选点,代价为当前连通块的顶点数量,求代价的期望值 百年难遇的点分治一遍AC!!! 今天又去翻了一下<具体数学 ...

  6. BZOJ3451 Tyvj1953 Normal 点分治 多项式 FFT

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3451.html 题目传送门 - BZOJ3451 题意 给定一棵有 $n$ 个节点的树,在树上随机点分 ...

  7. [BZOJ3451][Tyvj1953]Normal(点分治+FFT)

    https://www.cnblogs.com/GXZlegend/p/8611948.html #include<cmath> #include<cstdio> #inclu ...

  8. BZOJ3451 Tyvj1953 Normal 【期望 + 点分治 + NTT】

    题目链接 BZOJ3451 题解 考虑每个点产生的贡献,即为该点在点分树中的深度期望值 由于期望的线性,最后的答案就是每个点贡献之和 对于点对\((i,j)\),考虑\(j\)成为\(i\)祖先的概率 ...

  9. tyvj1953 Normal

    题目链接 正解:点分治+$FFT$. 很想吐槽一下$bzoj$,为什么搬了别的$oj$的题还设成权限题.. 首先我们考虑期望的线性性,即考虑每个点的贡献. 显然每个点的贡献就是它在点分树上的深度,所以 ...

随机推荐

  1. kali Linux 上编译并使用RFID核弹——proxmark3

    你还在在Windows下使用proxmark3?弱爆了! 本文作者:i春秋签约作家——冰尘 作为一个标准的日天日地日空气的(单身贵族泰迪)物理黑客Proxmark3这么高大上的东西应该是在键盘敲打声中 ...

  2. echart 遇到的点

    1,图表随着外部container变化而变化: window.onresize = myChart.resize (拿着resize在api文档中搜就看到了)

  3. Flask从入门到精通之数据模型之间的关系

    关系型数据库使用关系把不同表中的行联系起来.上篇随笔中介绍的用户和角色之间是一种简单的关系.即角色到用户的一对多关系,因为一个角色可属于多个用户,而每个用户都只能有一个角色.这种关系在模型中的表示方法 ...

  4. jvm内存结构(二)(栈的变化,机器指令的格式/执行模式)

    栈的结构: <Java虚拟机原理图解>4.JVM机器指令集 局部变量表: 方法执行时,虚拟机会把字节码中方法数据区的code类型的属性中的局部变量放到栈的局部变量表中. 操作栈: jvm指 ...

  5. OC 中的属性

    自动合成 (autosynthesis) @property 语法,会做下面两件事情 自动生成存取方法 由编译器生成,编辑器里不会看到这些方法. 向类中添加适当类型的实例变量 在属性前加下划线,作为实 ...

  6. 部署虚拟环境安装Linux系统

      目录                                                              准备工作 安装linux系统 重置root管理员密码 源代码编译 R ...

  7. 百度地图笔记_覆盖物(标注marker,折线polyline,多边形polygon)的点击弹窗和右键菜单

    利用绘制工具绘制点线面,并在执行绘制完成回调事件给相应覆盖物添加事件操作,提供标注的点击弹窗和标注.折线.多边形的右键删除 效果图如下: 完整代码如下:html+js <!DOCTYPE htm ...

  8. 【Java并发编程】:volatile变量修饰符

    volatile用处说明     在JDK1.2之前,java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的.而随着JVM的成熟和优化,现在在多线程环境下volatile关键 ...

  9. C/C++ -- Gui编程 -- Qt库的使用 -- 纯代码实现信号槽

    失败,系统找不着槽 #include<QtGui> int main(int argc, char * argv[]) { QApplication app(argc, argv); QT ...

  10. WebBench压力测试工具

    Webbench是有名的网站压力测试工具,它是由 Lionbridge公司(http://www.lionbridge.com)开发. Webbech能测试处在相同硬件上,不同服务的性能以及不同硬件上 ...