BZOJ3451: Tyvj1953 Normal
阿新 • • 發佈:2019-01-01
def for int fin 每次 點分治 const head n)
BZOJ3451: Tyvj1953 Normal
https://lydsy.com/JudgeOnline/problem.php?id=3451
分析:
- 根據期望的線性性,考慮有序點對\((x,y)\)對答案的貢獻。
- \(y\)需要是\((x,y)\)路徑上第一個被選中的點,對答案貢獻為\(\frac{1}{dis(x,y)}\)
- 點分治,按深度排序,每次\(fft\)來更新答案。
代碼:
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <set> #include <vector> #include <cmath> using namespace std; #define N 200050 typedef double f2; int head[N],to[N<<1],nxt[N<<1],cnt,n; int root,fk[N],siz[N],tot,used[N],md[N]; int aa[N],la; f2 ans[N]; const f2 pi=acos(-1); struct cp { f2 x,y; cp() {} cp(f2 x_,f2 y_) {x=x_,y=y_;} cp operator + (const cp &u) const {return cp(x+u.x,y+u.y);} cp operator - (const cp &u) const {return cp(x-u.x,y-u.y);} cp operator * (const cp &u) const {return cp(x*u.x-y*u.y,x*u.y+y*u.x);} }; void fft(cp *a,int len,int flg) { int i,j,k,t; cp w,wn,tmp; for(i=k=0;i<len;i++) { if(i>k) swap(a[i],a[k]); for(j=len>>1;(k^=j)<j;j>>=1) ; } for(k=2;k<=len;k<<=1) { t=k>>1; wn=cp(cos(2*flg*pi/k),sin(2*flg*pi/k)); for(i=0;i<len;i+=k) { w=cp(1,0); for(j=i;j<i+t;j++) { tmp=a[j+t]*w; a[j+t]=a[j]-tmp; a[j]=a[j]+tmp; w=w*wn; } } } if(flg==-1) for(i=0;i<len;i++) a[i].x/=len; } inline void add(int u,int v) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; } void gr(int x,int y) { int i; siz[x]=1; fk[x]=0; for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&!used[to[i]]) { gr(to[i],x); fk[x]=max(fk[x],siz[to[i]]); siz[x]+=siz[to[i]]; } fk[x]=max(fk[x],tot-siz[x]); if(fk[x]<fk[root]) root=x; } void gd(int x,int y) { int i; siz[x]=1; md[x]=1; for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&!used[to[i]]) { gd(to[i],x); md[x]=max(md[to[i]]+1,md[x]); siz[x]+=siz[to[i]]; } } inline bool cmp(const int &x,const int &y) {return md[x]<md[y];} int A[N],nowdep,B[N]; cp Pa[N],Pb[N]; void ggd(int x,int y,int d) { int i; B[d]++; for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&!used[to[i]]) { ggd(to[i],x,d+1); } } void solve(int x) { used[x]=1; int i,j; gd(x,0); la=0; for(i=head[x];i;i=nxt[i]) if(!used[to[i]]) aa[++la]=to[i]; sort(aa+1,aa+la+1,cmp); A[1]=1; nowdep=1; for(i=1;i<=la;i++) { ggd(aa[i],x,1); int z=md[aa[i]]+nowdep; int len=1; while(len<=z) len<<=1; for(j=0;j<len;j++) Pa[j]=cp(A[j],0),Pb[j]=cp(B[j],0); fft(Pa,len,1); fft(Pb,len,1); for(j=0;j<len;j++) Pa[j]=Pa[j]*Pb[j]; fft(Pa,len,-1); for(j=0;j<len;j++) ans[j]+=Pa[j].x; nowdep=md[aa[i]]+1; for(j=0;j<=nowdep;j++) A[j+1]+=B[j],B[j]=0; } for(i=0;i<=nowdep+1;i++) A[i]=0; for(i=head[x];i;i=nxt[i]) if(!used[to[i]]) { tot=siz[to[i]]; root=0; gr(to[i],x); solve(root); } } int main() { scanf("%d",&n); int i,x,y; for(i=1;i<n;i++) { scanf("%d%d",&x,&y); x++,y++; add(x,y); add(y,x); } fk[0]=1<<30; tot=n; gr(1,0); solve(root); f2 sum=0; for(i=1;i<=n;i++) { sum+=ans[i]/i; } printf("%.4f\n",sum*2+n); }
BZOJ3451: Tyvj1953 Normal