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,也可以多项式求逆 分治 ...
随机推荐
- centos7编译安装nginx
一.安装依赖包 yum install gcc gcc-c++ autoconf automake zlib zlib-devel openssl openssl-devel pcre-devel 二 ...
- c3p0数据源的第一次尝试
开始补习 以前学习过的基础 正在尝试从c3p0 获取到connection 好的,首先上代码吧 public static DataSource ds = null; static { ComboPo ...
- CSDN网站阅读更多:实现原理
一 设计案例 现在很多网站都增加了阅读更多功能.以CSDN为例,分析其实现原理. 二 设计原理 1 内容区的初始高度是固定的. 2 背景渐变的操作区,遮盖在内容区上面 3 点击按钮时,解除内容区的高度 ...
- c#线程池中的异常
static void Main(string[] args) { //写日志 //使用线程池 ; i < ; i++) { ThreadPool.QueueUserWorkItem(new W ...
- xmal中的渐变
<LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset=" ...
- SQL Server 异常解决:语句被终止。完成执行语句前已用完最大递归 100。
问题出现业务场景: 我司有个缺料分析报表,有一个字段是适用机种,需要通过BOM递归读取顶层父物料.这个错就是缺料分析报表执行时报的错: 原因分析定位: 通过网上一些资料,猜测应该是某个递归查询语句,遇 ...
- 盯着这where or 终于出了点感觉
AND 和 OR 运算符 AND 和 OR 可在 WHERE 子语句中把两个或多个条件结合起来. 如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录. 如果第一个条件和第二个条件中只要有 ...
- echarts 图表重新加载,原来的数据依然存在图表上
问题 在做一个全国地图上一些饼图,并且向省一级的地图钻取的时候,原来的饼图依然显示 原因 echars所有添加的图表都在一个series属性集合中,并且同一个echars对象默认是合并之前的数据的,所 ...
- Redis5种常用的数据结构
一.数据结构 五种常用的数据结构:string.hash.list.set.zse,以及三种不常用的:hyperloglog.geospatial.streams. 二.常用数据结构的使用 1.Str ...
- gambit软件license文件
最近自己的gambit软件license文件已经到期,后面采用fluent的license文件后,可以使用,但不能导入文件.不过通过努力,终于找到了可以实现导入文件的代码,并且可以实现无限期的使用fl ...