prime distance on a tree(点分治+fft)
最裸的点分治+fft,调了好久,太菜了。。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=,inf=1e9;
const double pi=acos(-);
int f[maxn],t,last[maxn],pre[maxn],other[maxn],siz[maxn],vis[maxn];
int mi,root,rev[maxn],dep,N,n,p[maxn],tot,is[maxn];
ll sum[maxn],c[maxn],cnt[maxn];
void add(int x,int y){++t;pre[t]=last[x];last[x]=t;other[t]=y;}
void getroot(int x,int fa,int ac){
f[x]=;
for(int i=last[x];i;i=pre[i]){
int v=other[i];
if(vis[v]||v==fa)continue;
getroot(v,x,ac);
f[x]=max(f[x],siz[v]);
}
f[x]=max(siz[ac]-siz[x],f[x]);//注意这里是siz[ac]而不是n;
if(f[x]<mi){mi=f[x];root=x;}
}
void dfs(int x,int fa,int d){
c[d]++;
for(int i=last[x];i;i=pre[i]){
int v=other[i];
if(vis[v]||v==fa)continue;
dfs(v,x,d+);
}
}
struct cp{
double r,i;
cp operator+(cp&t){cp tp;tp.r=r+t.r;tp.i=i+t.i;return tp;}
cp operator-(cp&t){cp tp;tp.r=r-t.r;tp.i=i-t.i;return tp;}
cp operator*(cp&t){cp tp;tp.r=r*t.r-i*t.i;tp.i=t.r*i+t.i*r;return tp;}
}A[maxn],B[maxn],tmp[maxn],wn,w,x,y;
void fft(cp a[],int n,int flag){
for(int i=;i<n;++i){
rev[i]=rev[i>>]>>;
if(i&)rev[i]|=(n>>);
}
for(int i=;i<n;++i)tmp[i]=a[rev[i]];
for(int i=;i<n;++i)a[i]=tmp[i];
for(int i=;i<=n;i<<=){
wn.r=cos(*pi/i);wn.i=flag*sin(*pi/i);
for(int j=;j<n;j+=i){
w.r=;w.i=;
for(int k=j;k<j+i/;++k){
x=a[k];y=a[k+i/]*w;
a[k]=x+y;a[k+i/]=x-y;
w=w*wn;
}
}
}
if(flag==-)for(int i=;i<n;++i)a[i].r/=n;
}
void Siz(int x,int fa){
siz[x]=;
for(int i=last[x];i;i=pre[i]){
int v=other[i];
if(v==fa||vis[v])continue;
Siz(v,x);
siz[x]+=siz[v];
}
}
void calc(ll a[],int n,int flag){
for(int i=;i<n;++i)A[i].r=a[i],A[i].i=;
for(int i=;i<n;++i)B[i].r=a[i],B[i].i=;
fft(A,n,);
fft(B,n,);
for(int i=;i<n;++i)A[i]=A[i]*B[i];
fft(A,n,-);
for(int i=;i<n;++i)sum[i]+=flag*(ll)(A[i].r+0.3);
}
void solve(int x){
mi=1e9;
ll res=;
Siz(x,);
for(N=;N<=siz[x];N<<=);
for(int i=;i<N;++i)cnt[i]=;
cnt[]=;
for(int i=last[x];i;i=pre[i]){
int v=other[i];
if(vis[v])continue;
for(N=;N<=*siz[v];N<<=);
for(int j=;j<N;++j)c[j]=;
dfs(v,x,);
calc(c,N,-);
for(int j=;j<N;++j)cnt[j]+=c[j];
}
for(N=;N<=siz[x];N<<=);
calc(cnt,N,);
/*for(int i=0;i<n;++i)cout<<A[i].r<<' ';
cout<<endl;*/
sum[]=;
}
void divont(int x){
mi=1e9;
Siz(x,);
getroot(x,,x);
int u=root;
//cout<<u<<endl;
solve(u);
vis[u]=;
for(int i=last[u];i;i=pre[i]){
int v=other[i];
if(!vis[v])divont(v);
}
}
int main(){
cin>>n;
int x,y;
for(int i=;i<n;++i){
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
divont();
for(int i=;i<=;++i){
if(!is[i]){p[++tot]=i;}
for(int j=;j<=tot&&i*p[j]<=;++j){
is[i*p[j]]=;
if(i%p[j]==)break;
}
}
double mu=(double)n*(n-)/,res=;
for(int i=;i<=tot&&p[i]<=n;++i){
res+=sum[p[i]];
}
res/=;
printf("%.7lf",double(res)/double(mu));
return ;
}
prime distance on a tree(点分治+fft)的更多相关文章
- CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT
Prime Distance On Tree Problem description. You are given a tree. If we select 2 distinct nodes unif ...
- [题解] Atcoder ABC 225 H Social Distance 2 生成函数,分治FFT
题目 首先还没有安排座位的\(m-k\)个人之间是有顺序的,所以先把答案乘上\((m-k)!\),就可以把这些人看作不可区分的. 已经确定的k个人把所有座位分成了k+1段.对于第i段,如果我们能求出这 ...
- bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3456 分治FFT: 设 dp[ i ] 表示 i 个点时连通的方案数. 考虑算补集:连通的方 ...
- BNUOJ 51279[组队活动 Large](cdq分治+FFT)
传送门 大意:ACM校队一共有n名队员,从1到n标号,现在n名队员要组成若干支队伍,每支队伍至多有m名队员,求一共有多少种不同的组队方案.两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中 ...
- 数论 - 素数的运用 --- poj 2689 : Prime Distance
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12512 Accepted: 3340 D ...
- UVA 10140 - Prime Distance(数论)
10140 - Prime Distance 题目链接 题意:求[l,r]区间内近期和最远的素数对. 思路:素数打表,打到sqrt(Max)就可以,然后利用大的表去筛素数.因为[l, r]最多100W ...
- poj 2689 Prime Distance(大区间素数)
题目链接:poj 2689 Prime Distance 题意: 给你一个很大的区间(区间差不超过100w),让你找出这个区间的相邻最大和最小的两对素数 题解: 正向去找这个区间的素数会超时,我们考虑 ...
- ural1471 Distance in the Tree
Distance in the Tree Time limit: 1.0 secondMemory limit: 64 MB A weighted tree is given. You must fi ...
- hdu 5730 Shell Necklace [分治fft | 多项式求逆]
hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ...
随机推荐
- 通过微信公众号API复制公众号自定义菜单同时增加子菜单方法
主要的原因是再不破坏公众号以前的菜单的基础上增加自定义菜单,主要步骤如下: 1.通过微信提供的微信公众平台接口调试工具获取公众号的所有自定义菜单 网址:https://mp.weixin.qq.com ...
- Idea使用maven搭建SpringMVC框架
https://www.cnblogs.com/shang-shang/p/7477607.html
- java中判断是否是一个无用的类
类需要同时满足以下三个条件才能算是无用的类: 1.该类所有的实例都已经被回收,也就是java堆中不存在类的任何实例 2.加载该类的ClassLoader已经被回收 3.该类对应的java.lang.C ...
- WPF网格绑定控件并控制控件是否可读
<DataGridTemplateColumn Width="100" Header="实测值"> <DataGridTemplateColu ...
- Windows内核驱动中操作文件
本页主题:如何在windows内核驱动中对文件操作,实现对文件的拷贝.粘贴.删除.查询信息等,这是很常用也是很简单的方法. 部分内容参考:http://www.cppblog.com/aurain/a ...
- 【SVN】关于提交代码时的问题
将项目上传到SVN弹出框提示One added/edited TODO item was found. Would you like to review it? 然后百度说这样解决: 造成这个原因是因 ...
- 窗体背景和png
窗体背景不要使用png格式图片,当窗体组件透明时,png会带来无穷的麻烦. 能不用png就不要用,截取图像也不要用Format32bppPArgb,特殊情况除外 Bitmap bkbmp = (Ima ...
- java第一章抽象和封装
面向过程和面向对象有什么区别? 面向过程的核心是函数,以功能为中心,实现了函数级别的代码重用. 面向对象的核心是封装了属性和方法(行为)的类,以数据为中心,实现了类级别的代码重用. 面向对象因为采用了 ...
- 第二篇 Flask 中的 Render Redirect HttpResponse
第二篇 Flask 中的 Render Redirect HttpResponse 1.Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返 ...
- PCIE4.0 简单介绍
关于PCI-E的标准,可以从2003年说起,2003年推出了PCI-E 1.0标准,在三年之后就推出了PCI-E 2.0,而在4年后的2010年就推出了PCI-E 3.0,但是在2010年之后的6年里 ...