BZOJ3451: Tyvj1953 Normal
题解:
好神的一道题。蒟蒻只能膜拜题解。
考虑a对b的贡献,如果a是a-b路径上第一个删除的点,那么给b贡献1。
所以转化之后就是求sigma(1/dist(i,j)),orz!!!
如果不是分母的话O(n)就可以搞,但是现在在分母上。。。
考虑转化一下,求ret[i]表示距离为i的点对有多少对。我们发现只要求出ret数组,然后就可以回答了。
如何求ret,我们用点分治。类似于RACE那道题。
对于一颗子树,我们整个信息一块统计,让它和前面的所有做卷积,更新ret,然后再把这棵子树归入前面的信息内。
代码:
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<map> #include<set> #include<queue> #include<string> #define inf 1000000000 #define maxn 50000+5 #define maxm 20000000+5 #define eps 1e-10 #define ll long long #define pa pair<int,int> #define for0(i,n) for(int i=0;i<=(n);i++) #define for1(i,n) for(int i=1;i<=(n);i++) #define for2(i,x,y) for(int i=(x);i<=(y);i++) #define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y;i;i=e[i].next) #define mod 1000000007 using namespace std; inline int read() { int x=,f=;char ch=getchar(); while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();} while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();} return x*f; }
int n,mx,m,len,cnt,sum,tot,rt,rev[maxn],head[maxn],d[maxn],f[maxn],s[maxn],g[maxn];
bool del[maxn];
ll ret[maxn];
const double PI=acos(-1.0);
struct cp
{
double x,y;
cp operator +(cp b){return (cp){x+b.x,y+b.y};}
cp operator -(cp b){return (cp){x-b.x,y-b.y};}
cp operator *(cp b){return (cp){x*b.x-y*b.y,x*b.y+y*b.x};}
};
cp a[*maxn],b[*maxn],c[*maxn],y[*maxn];
struct edge{int go,next;}e[*maxn];
inline void insert(int x,int y)
{
e[++tot]=(edge){y,head[x]};head[x]=tot;
e[++tot]=(edge){x,head[y]};head[y]=tot;
}
inline void getrt(int x,int fa)
{
s[x]=;f[x]=;
for4(i,x)if(!del[y=e[i].go]&&y!=fa)
{
getrt(y,x);
s[x]+=s[y];
f[x]=max(f[x],s[y]);
}
f[x]=max(f[x],sum-f[x]);
if(f[x]<f[rt])rt=x;
}
inline void getdep(int x,int fa,int w)
{
if(w>mx)mx=w;
d[++cnt]=w;
for4(i,x)if(!del[y=e[i].go]&&y!=fa)getdep(y,x,w+);
}
inline void get(int n)
{
n++;n=*n-;
m=,len=;
while(m<=n)m<<=,len++;
for0(i,m-)
{
int x=i,y=;
for1(j,len)y<<=,y|=x&,x>>=;
rev[i]=y;
}
}
inline void fft(cp *x,int n,int flag)
{
for0(i,n-)y[rev[i]]=x[i];
for0(i,n-)x[i]=y[i];
for(int m=;m<=n;m<<=)
{
cp wn=(cp){cos(2.0*PI*flag/m),sin(2.0*PI*flag/m)};
for(int i=;i<n;i+=m)
{
cp w=(cp){,};int mid=m>>;
for0(j,mid-)
{
cp u=x[i+j],v=x[i+j+mid]*w;
x[i+j]=u+v;x[i+j+mid]=u-v;
w=w*wn;
}
}
}
if(flag==-)for0(i,n-)x[i].x/=n;
}
inline void work(int x)
{
//cout<<"XXXXX"<<' '<<x<<' '<<"XXXX"<<endl;
del[x]=;mx=;
for4(i,x)if(!del[y=e[i].go])
{
cnt=;
getdep(y,x,);get(mx);
for0(j,m-)a[j]=(cp){g[j],},b[j]=(cp){,};
for1(j,cnt)b[d[j]].x+=,g[d[j]]++;
//for0(j,m-1)cout<<j<<' '<<a[j].x<<' '<<b[j].x<<endl;
fft(a,m,);fft(b,m,);
for0(j,m-)c[j]=a[j]*b[j];
fft(c,m,-);
for0(j,m-)ret[j]+=c[j].x+0.5;
//for0(j,m-1)cout<<j<<' '<<c[j].x<<' '<<c[j].y<<endl;
}
for1(i,mx)ret[i]+=g[i],g[i]=;
for4(i,x)if(!del[y=e[i].go])
{
sum=s[y];rt=;
getrt(y,);
work(rt);
}
} int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); n=read();
for1(i,n-)insert(read()+,read()+);
sum=n;f[rt=]=inf;
getrt(,);
work(rt);
double ans=0.0;
for1(i,n)
ans+=(double)ret[i]/(double)(i+);//cout<<i<<' '<<ret[i]<<endl;
printf("%.4f\n",n+*ans); return ; }
3451: Tyvj1953 Normal
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 125 Solved: 60
[Submit][Status]
Description
某天WJMZBMR学习了一个神奇的算法:树的点分治!
这个算法的核心是这样的:
消耗时间=0
Solve(树 a)
消耗时间 += a 的 大小
如果 a 中 只有 1 个点
退出
否则在a中选一个点x,在a中删除点x
那么a变成了几个小一点的树,对每个小树递归调用Solve
我们注意到的这个算法的时间复杂度跟选择的点x是密切相关的。
如果x是树的重心,那么时间复杂度就是O(nlogn)
但是由于WJMZBMR比较傻逼,他决定随机在a中选择一个点作为x!
Sevenkplus告诉他这样做的最坏复杂度是O(n^2)
但是WJMZBMR就是不信>_<。。。
于是Sevenkplus花了几分钟写了一个程序证明了这一点。。。你也试试看吧^_^
现在给你一颗树,你能告诉WJMZBMR他的傻逼算法需要的期望消耗时间吗?(消耗时间按在Solve里面的那个为标准)
Input
第一行一个整数n,表示树的大小
接下来n-1行每行两个数a,b,表示a和b之间有一条边
注意点是从0开始标号的
Output
一行一个浮点数表示答案
四舍五入到小数点后4位
如果害怕精度跪建议用long double或者extended
Sample Input
0 1
1 2
Sample Output
HINT
n<=30000
Source
BZOJ3451: Tyvj1953 Normal的更多相关文章
- BZOJ3451 Tyvj1953 Normal 点分治 多项式 FFT
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3451.html 题目传送门 - BZOJ3451 题意 给定一棵有 $n$ 个节点的树,在树上随机点分 ...
- [BZOJ3451][Tyvj1953]Normal(点分治+FFT)
https://www.cnblogs.com/GXZlegend/p/8611948.html #include<cmath> #include<cstdio> #inclu ...
- BZOJ3451 Tyvj1953 Normal 【期望 + 点分治 + NTT】
题目链接 BZOJ3451 题解 考虑每个点产生的贡献,即为该点在点分树中的深度期望值 由于期望的线性,最后的答案就是每个点贡献之和 对于点对\((i,j)\),考虑\(j\)成为\(i\)祖先的概率 ...
- 【BZOJ3451】Tyvj1953 Normal 点分治+FFT+期望
[BZOJ3451]Tyvj1953 Normal Description 某天WJMZBMR学习了一个神奇的算法:树的点分治!这个算法的核心是这样的:消耗时间=0Solve(树 a) 消耗时间 += ...
- bzoj 3451: Tyvj1953 Normal [fft 点分治 期望]
3451: Tyvj1953 Normal 题意: N 个点的树,点分治时等概率地随机选点,代价为当前连通块的顶点数量,求代价的期望值 百年难遇的点分治一遍AC!!! 今天又去翻了一下<具体数学 ...
- 【BZOJ3451】Normal
[BZOJ3451]Normal Description 某天WJMZBMR学习了一个神奇的算法:树的点分治! 这个算法的核心是这样的: 消耗时间=0 Solve(树 a) 消耗时间 += a 的 大 ...
- 【BZOJ3451】Normal (点分治)
[BZOJ3451]Normal (点分治) 题面 BZOJ 题解 显然考虑每个点的贡献.但是发现似乎怎么算都不好计算其在点分树上的深度. 那么考虑一下这个点在点分树中每一次被计算的情况,显然就是其在 ...
- 【bzoj3451】Tyvj1953 Normal 期望+树的点分治+FFT
题目描述 给你一棵 $n$ 个点的树,对这棵树进行随机点分治,每次随机一个点作为分治中心.定义消耗时间为每层分治的子树大小之和,求消耗时间的期望. 输入 第一行一个整数n,表示树的大小接下来n-1行每 ...
- BZOJ3451:Tyvj1953 Normal
根据期望的线性性,答案就是 \(\sum\) 每个连通块出现次数的期望 而每个连通块次数的期望就是 \(\sum\) 连通块的根与每个点连通次数的期望 也就是对于一条路径 \((i,j)\),设 \( ...
随机推荐
- python中执行javascript代码
python中执行javascript代码: 1.安装相应的库,我使用的是PyV8 2.import PyV8 ctxt = PyV8.JSContext() ctxt.enter() ...
- mac 下 sphinx + mysql + php 实现全文搜索(xampp)(4)php api 解析
1:function GetLastError() // 假如报错的话,会输出报错信息 2:function GetLastWarning ()// 输出 警告信息 3:function SetSe ...
- 导入 Mysql 示例数据库 employees
Mysql也有跟Oracle的scott与employees相似的数据库,这样就免除了每次都要自己建表并插入数据了. Mysql提供的供练习使用的数据库employees,下面地址:https://l ...
- 【socket】一分钟理清 socket udpsocket tcpsocket tcplistener TCPClient和 UDPClient
socket 套接字接口是各种语言tcp udp的网络操作的基础. 直接用socket 对象开发 可以选择 udpsocket 或者 tcpsocket ,两者在使用上仅一些方法和参数不同,所有的底 ...
- iOS:横向使用iPhone默认的翻页效果
大致思路使用两层辅助UIView的旋转来实现添加后的View的横向翻页效果 CATransform3D transformA = CATransform3DRotate(CATransform3DId ...
- Asp.net MVC 如何向webform一样在IIS里添加虚拟目录
相信很多用webform的程序猿都习惯性的使用虚拟目录的形式来对一个程序添加新的功能,那么在mvc下该如何来弄呢? 首先得有一个项目基层的项目,然后我们在这个项目的基础上新增一个功能模块,例如信息发布 ...
- MyBatis学习笔记之resultMap
使用mybatis不能不说的是resultMap 相比resultClass来说resultMap可以适应更复杂的关系映射,允许指定字段的数据类型,支持“select *” ,并不要求定义 Resul ...
- Webx常用接口
最近在学Webx框架, 在了解webx的工作流程后, 必须要会使用自带的接口和类 常用的 Navigator 这个接口中只有两种类型的方法, 及重定向与转发, 一般用在screen包下的类(注意:s ...
- EF当实体模型与数据库的架构不同时要删除数据库时的报错问题
当使用的EF的时候,我们都知道EF当实体模型与数据库的架构不同时要删除数据库,这是会把错: 无法创建与 'master' 数据库之间的连接,这是因为已打开原始数据库连接,并且已从连接字符串中删除凭据. ...
- 第一个js库文件
<!DOCTYPE html> <html xmlns=; ; } }; })(); ...