这题分三步:葺网(期望)、淀粉质(点分治)、蓉翅(容斥),再佐以芬芳团(FFT),一道巨难无比的 luogu 黑题就诞生了。

期望

先考虑在淀粉树上,\(i\) 点在 \(j\) 点的子树里的概率。实际上这个问题的每种情况相当于是 \(n\) 个点的各种排列方式。这也就相当于,我们在选择 \(j\) 点之前,没有选择路径 \((i,j)\) 上的其他点,那么 \(j\) 的子树内就会包含 \(i\),否则不会。那么 \(i\) 点在 \(j\) 点子树里的概率就是 \(\dfrac 1{dis(i,j)+1}\)。注意,这里的 \(dis(i,j)\) 是边的数量,而不是点的数量

由于期望具有可加性,所以相当于要求 \(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\dfrac 1{dis(i,j)+1}\)。这玩意可以直接转化为求解 \(num_k=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[dis(i,j)=k]\)。

点分治

此时想到点分治其实水到渠成,关键问题是如何求解。

实际上合并儿子信息的本质就是多项式乘法(因为相当于是两个儿子的信息配对),自然想到 FFT,但是直接把所有都乘到一起正确性会假,用统计“除 \(x\) 子树以外其他子树的信息和”的思想时间复杂度会炸,所以都不行。

容斥

注意力惊人的注意到可以容斥。我们将答案分成两个部分:所有情况(目前考虑的树内的任意两个点可以配对)和错误情况(两个点必须在同一个儿子的子树内),二者相减即为答案。实际上这两个东西都是子树内所有点的深度所得的多项式直接平方的结果。

这样就可以保证在 \(O(m\log m)\) 的时间复杂度内完成合并,加上点分治,时间复杂度为 \(O(n\log^2n)\)。

#include<bits/stdc++.h>
#define stp(x) fixed<<setprecision(x)
using namespace std;
const int N=1e5+5;
const long double pi=acos(-1);
namespace FFT{
struct comn{long double a,b;};
struct dft{vector<comn>fg;};
int rev[N],k,mx=1;
comn operator+(comn x,comn y){
return {x.a+y.a,x.b+y.b};
}comn operator-(comn x,comn y){
return {x.a-y.a,x.b-y.b};
}comn operator*(comn x,comn y){
return {x.a*y.a-x.b*y.b,x.b*y.a+x.a*y.b};
}void operator+=(comn &x,comn y){x=x+y;}
void operator-=(comn &x,comn y){x=x-y;}
void operator*=(comn &x,comn y){x=x*y;}
void init(int n){
k=0,mx=1;
while(mx<=n) mx*=2,k++;
for(int i=0;i<mx;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}void fft(dft &a,int n,int fl){
for(int i=0;i<n;i++)
if(i<rev[i]) swap(a.fg[i],a.fg[rev[i]]);
comn om={cos(pi),fl*sin(pi)},w={1,0};
for(int i=1;i<n;i*=2,om={cos(pi/i),fl*sin(pi/i)})
for(int j=0;j<n;j+=i*2,w={1,0})
for(int l=j;l<j+i;l++){
comn x=a.fg[l],y=w*a.fg[l+i];
a.fg[l]+=y,a.fg[l+i]=x-y,w*=om;
}
}void sat(dft &x,int len){
while(x.fg.size()<len) x.fg.push_back({0,0});
}void operator+=(dft &x,dft &y){
sat(x,y.fg.size());
for(int i=0;i<y.fg.size();i++) x.fg[i]+=y.fg[i];
}void operator-=(dft &x,dft &y){
for(int i=0;i<y.fg.size();i++) x.fg[i]-=y.fg[i];
}void pow2(dft &x){
int n=x.fg.size();rev[0]=0;
init(n+n),sat(x,mx),fft(x,mx,1);
for(int i=0;i<mx;i++) x.fg[i]*=x.fg[i];
fft(x,mx,-1);
for(int i=0;i<mx;i++) x.fg[i].a/=mx;
}
}using namespace FFT;
int n,dep[N],vis[N],sz[N],num[N];
long double ans;dft sum,c,d,al;vector<int>g[N];
void dfsrt(int x,int fa,int sm,int &rt){
sz[x]=1,num[x]=0;
for(auto y:g[x]){
if(y==fa||vis[y]) continue;
dfsrt(y,x,sm,rt),sz[x]+=sz[y];
num[x]=max(num[x],sz[y]),sz[y]=1;
}num[x]=max(num[x],sm-sz[x]);
if(num[x]<num[rt]) rt=x;
if(sz[x]==sm) sz[x]=1;
}void dfssz(int x,int fa){
for(auto y:g[x])
if(y!=fa&&!vis[y])
dfssz(y,x),sz[x]+=sz[y];
}void dfsp(int x,int fa,dft &id){
id.fg[dep[x]=dep[fa]+1].a++;
for(auto y:g[x])
if(y!=fa&&!vis[y]) dfsp(y,x,id);
}void solve(int x,int sm){
if(sm==1) return al.fg[0].a++,void();
d.fg.clear(),sat(d,sm);int rt=0;
sum.fg.clear(),sat(sum,sm),sum.fg[0].a=1;
dfsrt(x,0,sm,rt),dfssz(rt,0),vis[rt]=1,dep[rt]=0;
for(auto y:g[rt]) if(!vis[y]){
c.fg.clear(),sat(c,sz[y]+2);
dfsp(y,rt,c),sum+=c,pow2(c),d+=c;
}pow2(sum),sum-=d,al+=sum;
for(auto y:g[rt]) if(!vis[y]) solve(y,sz[y]);
}int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n,num[0]=1e9;
for(int i=1,x,y;i<n;i++){
cin>>x>>y,x++,y++;
g[x].push_back(y);
g[y].push_back(x);
}solve(1,n);
for(int i=0;i<n;i++)
ans+=al.fg[i].a/(i+1);
cout<<stp(4)<<ans;
return 0;
}//fast fourier transform

[BZOJ3451] Normal 题解的更多相关文章

  1. [BZOJ3451]normal 点分治,NTT

    [BZOJ3451]normal 点分治,NTT 好久没更博了,咕咕咕. BZOJ3451权限题,上darkbzoj交吧. 一句话题意,求随机点分治的期望复杂度. 考虑计算每个点对的贡献:如果一个点在 ...

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

    [BZOJ3451]Normal(点分治+FFT) 题面 给你一棵 n个点的树,对这棵树进行随机点分治,每次随机一个点作为分治中心.定义消耗时间为每层分治的子树大小之和,求消耗时间的期望. 分析 根据 ...

  3. BZOJ3451 Normal 期望、点分治、NTT

    BZOJCH传送门 题目大意:给出一棵树,求对其进行随机点分治的复杂度期望 可以知道一个点的贡献就是其点分树上的深度,也就是这个点在点分树上的祖先数量+1. 根据期望的线性性,考虑一个点对\((x,y ...

  4. bzoj3451 Normal

    题意:点分治每次随机选重心,求期望复杂度. 发现一次点分治的复杂度就是点分树上每个节点的子树大小之和.(并没有发现......) 看这个. 注意这个写法有问题,随便来个菊花图就是n2了. 每一层点分治 ...

  5. 【BZOJ3451】Normal (点分治)

    [BZOJ3451]Normal (点分治) 题面 BZOJ 题解 显然考虑每个点的贡献.但是发现似乎怎么算都不好计算其在点分树上的深度. 那么考虑一下这个点在点分树中每一次被计算的情况,显然就是其在 ...

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

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

  7. BZOJ3451: Tyvj1953 Normal

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

  8. 【BZOJ3451】Normal

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

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

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

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

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

随机推荐

  1. VLM-OCR-Demo:一个使用VLM用于OCR任务的示例

    前言 上一篇文章TesseractOCR-GUI:基于WPF/C#构建TesseractOCR简单易用的用户界面中我们构建了一个方便使用TesseractOCR的用户界面,今天构建一个类似的界面,使用 ...

  2. PCB设计AD规则设置(按照嘉立创设置)

    本文转载自https://blog.csdn.net/subtitle_/article/details/121648972 官方参考https://www.jlc.com/portal/vtechn ...

  3. 11C++循环结构-for循环(1)

    一.for语句 引出问题: 当需要重复执行某一语句时,使用for语句.for语句最常用的格式为: for (循环变量赋初值:循环条件:循环变量增值) 语句: 注: "语句:"就是循 ...

  4. node 生成api文档 使用apidoc

    先给大家看一下使用apidoc生成文档之后的视图,如果是所需的样子,可以继续往下看, 开始操作 1. 需要全局安装apidoc npm i apidoc -g 2. 生成配置文件 两种方法(用哪个都可 ...

  5. Xcode Swift自动格式化

    Xcode Swift自动格式化 安装SwiftFormat SwiftFormat 是一款用来格式化Swift代码的命令行工具. 直接用Homebrew安装 brew install swiftfo ...

  6. flutter问题汇总

    Text文字居中 Text(           'You will need to post a photo before you can play!',           textAlign:  ...

  7. Mac idea 打不开

    从官网上刚下载的idea,安装完成之后,双击打开,只见一闪而过,软件没有打开. 打开 访达->应用程序->IntelliJ IDEA ->显示包内容 :   image.png 显示 ...

  8. java判断反射的Field是不是用final修饰

    今天调用Field.set方法报错: Caused by: java.lang.IllegalAccessException: Can not set static final long field ...

  9. 龙哥量化:MACD指标的金叉死叉,这样使用更准确(图解)

    如果您需要代写技术指标公式, 请联系我. 龙哥QQ:591438821 龙哥微信:Long622889 本文的策略过于简单,你可以加一些更复杂的限制条件 1.水上金叉,可看涨; 2.水上死叉,是洗盘; ...

  10. [转]快速搭建简单的LBS程序——地图服务

    很多时候,我们的程序需要提供需要搭建基于位置的服务(LBS),本文这里简单的介绍一下其涉及的一些基本知识. 墨卡托投影 地图本身是一个三维图像,但在电脑上展示时,往往需要将其转换为二维的平面图形,需要 ...