CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT
Prime Distance On Tree
Problem description.
You are given a tree. If we select 2 distinct nodes uniformly at random, what's the probability that the distance between these 2 nodes is a prime number?
Input
The first line contains a number N: the number of nodes in this tree.
The following N-1 lines contain pairs a[i] and b[i], which means there is an edge with length 1 between a[i] and b[i].
Output
Output a real number denote the probability we want.
You'll get accept if the difference between your answer and standard answer is no more than 10^-6.
Constraints
2 ≤ N ≤ 50,000
The input must be a tree.
Example
Input:
5
1 2
2 3
3 4
4 5 Output:
0.5
Explanation
We have C(5, 2) = 10 choices, and these 5 of them have a prime distance:
1-3, 2-4, 3-5: 2
1-4, 2-5: 3
Note that 1 is not a prime number.
题意:
给你一颗树,n个点,n-1条边
让你求任意选两个不同的点,其距离是素数的概率
题解:
点分治
求出只经过重心的所有路径深度种类数
让属于不同的子树的点,利用其深度进行任意组合(FFT加速)求出最后组合结果
累积是素数的答案即可,复杂度 n* logn * logn
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 3e5+, M = 1e6+, mod = 1e9+,inf = 2e9; struct Complex {
double r , i ;
Complex () {}
Complex ( double r , double i ) : r ( r ) , i ( i ) {}
Complex operator + ( const Complex& t ) const {
return Complex ( r + t.r , i + t.i ) ;
}
Complex operator - ( const Complex& t ) const {
return Complex ( r - t.r , i - t.i ) ;
}
Complex operator * ( const Complex& t ) const {
return Complex ( r * t.r - i * t.i , r * t.i + i * t.r ) ;
}
} ; void FFT ( Complex y[] , int n , int rev ) {
for ( int i = , j , t , k ; i < n ; ++ i ) {
for ( j = , t = i , k = n >> ; k ; k >>= , t >>= ) j = j << | t & ;
if ( i < j ) swap ( y[i] , y[j] ) ;
}
for ( int s = , ds = ; s <= n ; ds = s , s <<= ) {
Complex wn = Complex ( cos ( rev * * pi / s ) , sin ( rev * * pi / s ) ) , w ( , ) , t ;
for ( int k = ; k < ds ; ++ k , w = w * wn ) {
for ( int i = k ; i < n ; i += s ) {
y[i + ds] = y[i] - ( t = w * y[i + ds] ) ;
y[i] = y[i] + t ;
}
}
}
if ( rev == - ) for ( int i = ; i < n ; ++ i ) y[i].r /= n ;
}
Complex s[N],t[N]; int vis[N],f[N],siz[N],n,allnode,root;
int P[N];
vector<int > G[N];
void init() {
for(int i = ; i <= *n; ++i) {
if(!P[i]) {
for(int j = i+i; j <= *n; j += i)
P[j] = ;
}
}
P[] = ;
for(int i = ; i <= n; ++i) vis[i] = ;
}
void getroot(int u,int fa) {
f[u] = ;
siz[u] = ;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i];
if(vis[to] || to == fa) continue;
getroot(to,u);
siz[u] += siz[to];
f[u] = max(f[u],siz[to]);
}
f[u] = max(f[u], allnode - siz[u]);
if(f[u] < f[root]) root = u;
} int len = ,cnt[N],dep[N],nowcnt[N],mxdep;
LL ans = ;
void getdeep(int u,int f) {
siz[u] = ;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i];
if(vis[to] || to == f) continue;
dep[to] = dep[u] + ;
getdeep(to,u);
mxdep = max(mxdep,dep[to]);
siz[u] += siz[to];
}
}
void dfs(int u,int f,int p) {
nowcnt[dep[u]]+=p;
if(p == -) cnt[dep[u]] += ;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i];
if(vis[to] || to == f) continue;
dfs(to,u,p);
}
}
LL cal(int u) {
LL ret = ;
for(int i = ; i <= n; ++i) cnt[i] = ;
cnt[] = ;
dep[u] = ;
mxdep = -;
getdeep(u,);
len = ;
while(len <= *mxdep) len<<=;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i];
if(vis[to]) continue;
dfs(to,u,);
for(int j = ; j < len; ++j) t[j] = Complex(nowcnt[j],);
for(int j = ; j < len; ++j) s[j] = Complex(cnt[j],); FFT(s,len,);FFT(t,len,);
for(int j = ; j < len; ++j) s[j] = s[j] * t[j];
FFT(s,len,-);
for(int j = ;j < len; ++j) {
LL tmp = (s[j].r+0.5); if(P[j]) continue; ret += tmp;
}
dfs(to,u,-);
}
return ret;
}
void work(int u) {
vis[u] = ;
ans += cal(u);
// exit(0);
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i];
if(vis[to]) continue;
allnode = siz[to];
root = ;
getroot(to,);
work(root);
}
}
int main() {
scanf("%d",&n);
while(len <= n) len<<=;
init();
for(int i = ; i < n; ++i) {
int x,y;
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
} ans = ;
f[] = inf;root = ;allnode = n;
getroot(,);
work(root);
printf("%.6f\n",(double)1.0*ans/((double)n*(n-)/));
return ;
}
CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT的更多相关文章
- 【CodeChef】Prime Distance On Tree
vjudge 给定一棵边长都是\(1\)的树,求有多少条路径长度为质数 树上路径自然是点分治去搞,但是发现要求是长度为质数,总不能对每一个质数都判断一遍吧 自然是不行的,这个东西显然是一个卷积,我们合 ...
- codechef Prime Distance On Tree(树分治+FFT)
题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...
- prime distance on a tree(点分治+fft)
最裸的点分治+fft,调了好久,太菜了.... #include<iostream> #include<cstring> #include<cstdio> #inc ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- POJ 1741.Tree 树分治 树形dp 树上点对
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 24258 Accepted: 8062 Description ...
- poj 1744 tree 树分治
Tree Time Limit: 1000MS Memory Limit: 30000K Description Give a tree with n vertices,each ed ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- HDU4670 Cube number on a tree 树分治
人生的第一道树分治,要是早点学我南京赛就不用那么挫了,树分治的思路其实很简单,就是对子树找到一个重心(Centroid),实现重心分解,然后递归的解决分开后的树的子问题,关键是合并,当要合并跨过重心的 ...
随机推荐
- 【Android】监听viewpager子页面里面的Button按钮
最近做项目遇到Viewpager+Fragment滑动页面,要监听子页面中的按钮,在网上查了些解决办法: 办法一: 这种方法是在适配器初始化中进行监听,有人亲测通过,但是我继承FragmentPage ...
- 【Luogu】P3455Zip-Queries(莫比乌斯反演)
题目链接 真是神TM莫比乌斯 首先来看一个神奇的结论:求gcd(x,y)==k的对数,其中1<=x<=n,1<=y<=m 等同于求gcd(x,y)==1的对数,其中1<= ...
- BZOJ-1303 中位数图
先找到B的位置x,然后依次统计A[i..x-1](0<i<x)中小于B的个数,和A[x+1..i](x<i<n)中大于B的个数 最后Answer等于(左边有i个小于B的情况总数 ...
- 源码分析 脱壳神器ZjDroid工作原理
0. 神器ZjDroid Xposed框架的另外一个功能就是实现应用的简单脱壳,其实说是Xposed的作用其实也不是,主要是模块编写的好就可以了,主要是利用Xposed的牛逼Hook技术实现的,下面就 ...
- java.lang.Class解析
java.lang.Class 1.java.lang.Class的概念 当一个类或接口被装入的JVM时便会产生一个与之关联的java.lang.Class对象,java.lang.class类就是用 ...
- bzoj2648/2716 kdtree
SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 5199 Solved: 1813[Submit][Status][Discuss] D ...
- centos7 下修改网络配置
修改ip地址 编辑 /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=Ethernet BOOTPROTO=static 静态ip DEFROUTE=yes ...
- 星球大战 BZOJ 1015
星球大战 [问题描述] 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过 ...
- MongoDB_语法命令
可以通过MongoDB shell 来连接MongoDB服务: ./mongo 进入交互 数据库-->集合-->文档 几个文档就组成了集合,可以设置固定大小的集合,集合就会有过期机制, ...
- 【微信小程序】开发实战 之 「配置项」与「逻辑层」
微信小程序作为微信生态重要的一环,在实际生活.工作.商业中的应用越来越广泛.想学习微信小程序开发的朋友也越来越多,本文将在小程序框架的基础上就微信小程序项目开发所必需的基础知识及语法特点进行了详细总结 ...