[BZOJ3451][Tyvj1953]Normal
来源:互联网 发布:量子 知乎 编辑:程序博客网 时间:2024/06/07 07:36
题目大意
给定一棵
计算这个点分治的期望时间复杂度。
题目分析
首先显然可以看出,每个点对时间复杂度的是其在点分树上的深度。考虑对每个点分开计算贡献,现在相当于要求每个点在点分树上的期望深度之和。
定义
那么答案显然是
考虑
所以答案其实就是
考虑用点分治加FFT统计出不同距离的点对的个数,最后扫一遍求答案就好了。
时间复杂度
代码实现
#include <algorithm>#include <iostream>#include <cstdio>#include <cctype>#include <cmath>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}typedef long double db;const db pi=acos(-1);const int N=65600;const int E=N<<1;struct Z{ db x,y; inline Z(db x_=0.,db y_=0.){x=x_,y=y_;} inline Z operator+(Z const p)const{return Z(x+p.x,y+p.y);} inline Z operator-(Z const p)const{return Z(x-p.x,y-p.y);} inline Z operator*(Z const p)const{return Z(x*p.x-y*p.y,x*p.y+y*p.x);} inline Z operator/(db const k)const{return Z(x/k,y/k);}}A[N],t[N],omega[N];int last[N],fa[N],size[N],que[N],depth[N],dis[N],cnt[N],tmp[N],trs[N];int tov[E],nxt[E];bool vis[N];int n,tot,head,tail,L;db ans;void insert(int x,int y){tov[++tot]=y,nxt[tot]=last[x],last[x]=tot;}void DFT(Z *a,int len,int sig){ for (int i=0;i<len;++i) t[trs[i]]=A[i]; for (int l=2,half,p;l<=len;l<<=1) { half=l>>1,p=len/l; for (int i=0;i<half;++i) { Z w=omega[sig>0?p*i:len-p*i]; for (int j=i;j<len;j+=l) { Z u=t[j],v=w*t[j+half]; t[j]=u+v,t[j+half]=u-v; } } } for (int i=0;i<len;++i) A[i]=t[i];}void FFT(Z *a,int len){ DFT(a,len,1); for (int i=0;i<len;++i) a[i]=a[i]*a[i]; DFT(a,len,-1); for (int i=0;i<len;++i) a[i]=a[i]/len;}void pre(int len){ for (L=1;L<=len;L<<=1); for (int i=0;i<L;++i) { int ret=0; for (int j=1,x=i;j<L;j<<=1,x>>=1) ret=ret<<1|(x&1); trs[i]=ret; } for (int i=0;i<=L;++i) omega[i]=Z(cos(2.*i*pi/L),sin(2.*i*pi/L));}int core(int og){ int rets=n,ret,i,x,y,tmp; for (head=0,fa[que[tail=1]=og]=0,dis[og]=1;head<tail;) for (i=last[x=que[++head]],size[x]=1;i;i=nxt[i]) if ((y=tov[i])!=fa[x]&&!vis[y]) fa[que[++tail]=y]=x,dis[y]=dis[x]+1; for (head=tail;head>1;--head) size[fa[que[head]]]+=size[que[head]]; for (head=1;head<=tail;++head) { for (i=last[x=que[head]],tmp=size[og]-size[x];i;i=nxt[i]) if ((y=tov[i])!=fa[x]&&!vis[y]) tmp=max(tmp,size[y]); if (rets>tmp) ret=x,rets=tmp; } return ret;}void solve(int x){ int c=core(x),mxd=0; if (size[x]!=n) { for (int head=1;head<=tail;++head) mxd=max(mxd,dis[que[head]]); for (int i=0;i<=mxd;++i) tmp[i]=0; for (int head=1;head<=tail;++head) ++tmp[dis[que[head]]]; pre(mxd*2); for (int i=0;i<L;++i) A[i]=Z((i<=mxd?tmp[i]:0),0); FFT(A,L); for (int i=0;i<=mxd*2;++i) cnt[i+1]-=(int)round(A[i].x); mxd=0; } for (depth[c]=0,head=0,fa[que[tail=1]=c]=0;head<tail;mxd=max(mxd,depth[x])) for (int i=last[x=que[++head]],y;i;i=nxt[i]) if ((y=tov[i])!=fa[x]&&!vis[y]) fa[que[++tail]=y]=x,depth[y]=depth[x]+1; for (int i=0;i<=mxd;++i) tmp[i]=0; for (int head=1;head<=tail;++head) ++tmp[depth[que[head]]]; pre(mxd*2); for (int i=0;i<L;++i) A[i]=Z((i<=mxd?tmp[i]:0),0); FFT(A,L); for (int i=0;i<=mxd*2;++i) cnt[i+1]+=(int)round(A[i].x); vis[c]=1; for (int i=last[c],y;i;i=nxt[i]) if (!vis[y=tov[i]]) solve(y);}int main(){ freopen("normal.in","r",stdin),freopen("normal.out","w",stdout); n=read(); for (int i=1,x,y;i<n;++i) x=read()+1,y=read()+1,insert(x,y),insert(y,x); solve(1); for (int i=1;i<=n;++i) ans+=cnt[i]*(1./i); printf("%.4lf\n",(double)ans); fclose(stdin),fclose(stdout); return 0;}
0 0
- BZOJ3451 Tyvj1953 Normal
- [bzoj3451]Tyvj1953 Normal
- 【bzoj3451】【Tyvj1953】Normal 题解
- [BZOJ3451][Tyvj1953]Normal
- bzoj3451/Tyvj1953:Normal(点分治+FFT)
- bzoj 3451: Tyvj1953 Normal
- BZOJ3451 Normal 点分治+FFT
- Tyvj1953:Normal (点分治+FFT)
- bzoj3451
- normal
- Normal
- Normal Mapping
- normal form
- normal transform
- Normal Distribute
- Normal Map
- vertex normal
- Normal Mapping
- Spark源码系列(九)Spark SQL初体验之解析过程详解
- 如何利用Element元素在末尾添加节点
- python3.6连接MySQL
- Codeforces #410(div2) B. Mike and strings (暴力枚举
- 积分系统(3)-详细公告页面之Controller层
- [BZOJ3451][Tyvj1953]Normal
- Captcha Cracker
- Leetcode-标签为Tree 543. Diameter of Binary Tree
- LeetCode#160.Intersection of Two Linked Lists
- innerHTML使用入门
- 关于JDBC中的Mysql驱动所遇到的坑
- 逆向工程核心原理学习笔记(四):检索API方法2-设置断点
- ssh 事务不能回滚的问题总结
- 1分钟实现“延迟消息”功能