Forest Game 【期望】【点分治】【FFT】

题目要求计算一棵树在删除所有点后,期望得分乘以全排列数N!的值。最初误解了N!的作用,后来发现它无关紧要。重新思考后,通过节点对节点的贡献概率来解决,即节点u对v有贡献当且仅当u是第一条被删除的点。问题转化为求不同长度路径的数量,长度1的路径除外,需要计算两次。利用点分治结合快速傅里叶变换(FFT)进行高效求解,整体复杂度为O(N * logN * logN)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:https://vjudge.net/problem/Gym-101234D

题目大意:给一颗树,共N个点,每次随机选择一个点,得分加上该点所在树的大小,然后删除这个点,断开与其相连的所有边,问删完所有点所获得的   期望得分乘N! 是多少。

emmm被这个乘N! 给坑了,以为这是个假的期望题目,因为全排列共N!种, 期望乘N! 其实就是全排列的和,觉得这是出题人留的解题思路.....然后就去考虑和的问题了,从此走上了不归路。

 

看了题解后发现,这个N! 一点用都没有啊啊啊啊啊啊啊。

重新用期望的方式开始思考,我们考虑节点u对节点v的贡献,u对v有贡献当且仅当u是u->v这条链上第一个删除的点,概率为1/len(len是该链上点的个数,包含端点)。

然后就变成了求树上每种长度(长度定义为路径上点数)的路径条数的模板,除了长度为1的以外,都需要算2次。

点分治的过程中使用fft合并就可以了。

复杂度O (N * logN * logN)

#include <bits/stdc++.h>
#define ll long long
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define pb push_back
#define ll long long
using namespace std;
const int M = 1e5+1000;
const int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值