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,也可以多项式求逆 分治 ...
随机推荐
- 什么是云?Iaas,Paas和SaaS
周围的朋友听说我是做云相关的,总是爱问啥是云?别不是虚幻的概念吧.云计算当然不是虚幻的概念,“云”其实是互联网的一个隐喻,简单地说,云计算是通过Internet(“云”)交付计算服务——服务器.存储. ...
- PhoenixFD插件流体模拟——UI布局【Interaction】详解
流体交互 本文主要讲解Interaction折叠栏中的内容.原文地址:https://docs.chaosgroup.com/display/PHX3MAX/Liquid+Interaction 主要 ...
- TZOJ 2569 Wooden Fence(凸包求周长)
描述 Did you ever wonder what happens to your money when you deposit them to a bank account? All banks ...
- 2018-2019-2 20165315 《网络对抗技术》Exp4 恶意代码分析
2018-2019-2 20165315 <网络对抗技术>Exp4 恶意代码分析 一.实验要求 1.系统运行监控 使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP是 ...
- 笔记之monkey自定义脚本
自定义脚本的稳定性测试 常规MOnkey测试执行的是随机的事件流,但如果只是想让Monkey测试某个特定场景者时候就需要用到自定义脚本,Monkey支持执行用户自定义脚本的测试,用户之需要按照Monk ...
- C# Task.Run 和 Task.Factory.StartNew 区别
Task.Run 是在 dotnet framework 4.5 之后才可以使用,但是 Task.Factory.StartNew 可以使用比 Task.Run 更多的参数,可以做到更多的定制.可以认 ...
- 010 Editor 8.0.1 之 逆向分析及注册机编写
前言一.工具及软件介绍二.逆向分析2.1.找到提示错误注册弹窗2.2.分析跳转处代码2.3.=2D 函数分析2.3.1.获取注册码处分析2.3.2.3处分支分析2.3.2.1.9C情况2.3.2.2. ...
- 聚簇索引(Clustered Index)和非聚簇索引 (Non- Clustered Index)
本文转自https://my.oschina.net/u/1866821/blog/297673 索引的重要性数据库性能优化中索引绝对是一个重量级的因素,可以说,索引使用不当,其它优化措施将毫无意义. ...
- Lonsdor K518ISE programs 2005 Ford Focus key in two minutes
A quick demonstration of Lonsdor K518ISE programming key for 2005 Ford Focus in two minutes. And for ...
- appnium启动报错Encountered internal error running command: Error: Error occured while starting App. Original error: Permission to start activity denied.
说明写错了activity 首先查看一下activity,使用命令 打开被测app,输入命令adb shell dumpsys window | findstr mCurrentFocus 看似这个a ...