vjudge

给定一棵边长都是\(1\)的树,求有多少条路径长度为质数

树上路径自然是点分治去搞,但是发现要求是长度为质数,总不能对每一个质数都判断一遍吧

自然是不行的,这个东西显然是一个卷积,我们合并的时候显然可以直接大力\(NTT\)

但是需要注意的是我们访问子树的顺序必须是先访问深度小的子树,否则轻松被菊花加长链卡掉

但是\(CodeChef\)数据水啊,就这样直接搞过去了

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=1e5+5;
const int inf=1e9;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt;}e[maxn];
const LL mod=998244353;
const LL G[2]={3,332748118};
int sum[maxn],mx[maxn],vis[maxn],st[maxn];
int now,S,rt,top,n,num,head[maxn],tax[maxn];
int f[maxn],p[maxn>>1];
int rev[262145],len,L;
LL A[262145],B[262145],ans;
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
inline LL ksm(LL a,int b) {
LL S=1;
while(b) {if(b&1) S=S*a%mod;b>>=1;a=a*a%mod;}
return S;
}
inline void NTT(LL *f,int o) {
for(re int i=0;i<len;i++)
if(i<rev[i]) std::swap(f[i],f[rev[i]]);
for(re int i=2;i<=len;i<<=1) {
int ln=i>>1;LL og1=ksm(G[o],(mod-1)/i);
for(re int l=0;l<len;l+=i) {
LL t,og=1;
for(re int x=l;x<l+ln;++x) {
t=(og*f[ln+x])%mod;
f[ln+x]=(f[x]-t+mod)%mod;
f[x]=(f[x]+t)%mod;
og=(og*og1)%mod;
}
}
}
if(!o) return;
LL inv=ksm(len,mod-2);
for(re int i=0;i<len;i++) f[i]=(f[i]*inv)%mod;
}
inline void mul() {
int m=0;
for(re int i=1;i<=top;i++) m=max(m,st[i]);
if(!L) {L=m;return;}
for(re int i=1;i<=top;i++) B[st[i]]++;
len=1;while(len<m+L+2) len<<=1;
for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
for(re int i=1;i<=L;i++) A[i]=tax[i];
NTT(A,0),NTT(B,0);
for(re int i=0;i<len;i++) A[i]=(A[i]*B[i])%mod;
NTT(A,1);
for(re int i=1;i<=p[0]&&p[i]<=L+m;i++) ans+=A[p[i]];
L=max(L,m);
for(re int i=0;i<len;i++) A[i]=B[i]=0;
}
void getroot(int x,int fa) {
sum[x]=1;mx[x]=0;
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]||e[i].v==fa) continue;
getroot(e[i].v,x);
sum[x]+=sum[e[i].v];
mx[x]=max(mx[x],sum[e[i].v]);
}
mx[x]=max(mx[x],S-sum[x]);
if(mx[x]<now) now=mx[x],rt=x;
}
void getdis(int x,int fa,int L) {
st[++top]=L;
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]||e[i].v==fa) continue;
getdis(e[i].v,x,L+1);
}
}
void dfs(int x) {
vis[x]=1;
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]) continue;
top=0;getdis(e[i].v,x,1);
for(re int j=1;j<=top;j++)
if(!f[st[j]]) ans++;
mul();
for(re int j=1;j<=top;j++) tax[st[j]]++;
}
for(re int i=1;i<=L;i++) tax[i]=0;
L=0;
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]) continue;
S=sum[e[i].v];now=inf;
getroot(e[i].v,x);dfs(rt);
}
}
int main() {
n=read();
for(re int x,y,i=1;i<n;i++)
x=read(),y=read(),add(x,y),add(y,x);
f[1]=1;
for(re int i=2;i<=n;i++) {
if(!f[i]) p[++p[0]]=i;
for(re int j=1;j<=p[0]&&p[j]*i<=n;j++) {
f[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
S=n,now=inf;getroot(1,0);dfs(rt);
LL C=(LL)n*(LL)(n-1)/2ll;
printf("%.6lf\n",(double)ans/(double)C);
return 0;
}

【CodeChef】Prime Distance On Tree的更多相关文章

  1. 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 ...

  2. 【UVA10140】Prime Distance

    题目大意:求出一个给定区间 [l, r] 内相邻素数之间的最大距离和最小距离. 题解:由于 l, r 的范围太大,没法直接用筛法得出区间的素数.考虑筛出区间的素数等价于筛掉区间内的所有和数, 根据算术 ...

  3. 一本通1619【例 1】Prime Distance

    1619: [例 1]Prime Distance 题目描述 原题来自:Waterloo local,题面详见 POJ 2689 给定两个整数 L,R,求闭区间 [L,R] 中相邻两个质数差值最小的数 ...

  4. 【LeetCode】二叉查找树 binary search tree(共14题)

    链接:https://leetcode.com/tag/binary-search-tree/ [220]Contains Duplicate III (2019年4月20日) (好题) Given ...

  5. 【BZOJ2959】长跑(Link-Cut Tree,并查集)

    [BZOJ2959]长跑(Link-Cut Tree,并查集) 题面 BZOJ 题解 如果保证不出现环的话 妥妥的\(LCT\)傻逼题 现在可能会出现环 环有什么影响? 那就可以沿着环把所有点全部走一 ...

  6. 【BZOJ2588】Count On a Tree(主席树)

    [BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...

  7. 【BZOJ2816】【ZJOI2012】网络(Link-Cut Tree)

    [BZOJ2816][ZJOI2012]网络(Link-Cut Tree) 题面 题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相 ...

  8. 【CodeChef】Querying on a Grid(分治,最短路)

    [CodeChef]Querying on a Grid(分治,最短路) 题面 Vjudge CodeChef 题解 考虑分治处理这个问题,每次取一个\(mid\),对于\(mid\)上的三个点构建最 ...

  9. 【CF434E】Furukawa Nagisa's Tree 点分治

    [CF434E]Furukawa Nagisa's Tree 题意:一棵n个点的树,点有点权.定义$G(a,b)$表示:我们将树上从a走到b经过的点都拿出来,设这些点的点权分别为$z_0,z_1... ...

随机推荐

  1. CSS相对定位|绝对定位(五)之z-index篇——张鑫旭

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1855 补充于2016 ...

  2. python中深浅拷贝

    python的复制,深拷贝和浅拷贝的区别   在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...

  3. 转:ubuntu 18.04 LTS 安装 java10(JDK) 及问题说明

    原文地址:ubuntu 18.04 LTS 安装 java10 及问题说明 1.下载相应的安装包,例如jdk-10.0.1_linux-x64_bin.tar.gz.下载地址: http://www. ...

  4. PHP中的prepare准备语句的意义

    mysqli和PDO扩展都有prepare这个语法,刚开始以为只是单纯的语法,没想到,还是有实际意义的: “每次发送查询语句给MySQL服务时,都必须解析该查询的语法,确保结构正确并能够执行.这是这个 ...

  5. ios 下拉列表

    #import <UIKit/UIKit.h> @class FVPullDownMenu; /** 指示器状态*/ typedef enum { IndicatorStateShow = ...

  6. elixir 基础数据结构

     Elixir中的一些基础的数据结构:整数,浮点数,字符串,原子,列表,元组  整数,浮点数,字符串 跟其他语言差不多  原子:名字为值的常量  在ruby类似Symbols  在erlang是用大写 ...

  7. 使用servicestack连接redis

    引言:作为少有的.net架构下的大型网站,stackoverflow曾发表了一篇文章,介绍了其技术体系,原文链接http://highscalability.com/blog/2011/3/3/sta ...

  8. CentOS7系列--1.3CentOS7用户管理

    CentOS7用户管理 1. 添加用户 [root@centos7 ~]# useradd jack [root@centos7 ~]# passwd jack Changing password f ...

  9. ASP.NET MVC 实现区域 项目分离 (比较好的方式)

    说明: ZRT.Web 是前台网站,目录[D:\ZRT.Web\] ZRT.Admin 是后台管理,目录[D:\ZRT.Web\Applications\Admin\],删除文件[Global.asa ...

  10. C语言中的逗号表达式

    转载:http://www.cnblogs.com/hnrainll/archive/2011/08/03/2126660.html C语言提供一种特殊的运算符——逗号运算符.用它将两个表达式连接起来 ...