Codeforces Gym 101234D Forest Game
2017-06-18 21:36
495 查看
我们枚举两个点,考虑它们之间的贡献。如果u和v之间的距离为d,那么u对v有1的贡献当且仅当这条路径上v被第一个删除,概率是1d+1。因此我们只需要求出这些点两两之间的距离。点分治的时候用FFT计算就可以了,复杂度O(nlog2n)。
#include<cstdio> #include<cmath> #include<algorithm> #include<vector> using namespace std; #define LL long long const int maxn=400010,p=1000000007; const double pi=acos(-1); struct Complex { double a,b; Complex operator + (const Complex &c) const { return (Complex){a+c.a,b+c.b}; } Complex operator - (const Complex &c) const { return (Complex){a-c.a,b-c.b}; } Complex operator * (const Complex &c) const { return (Complex){a*c.a-b*c.b,a*c.b+b*c.a}; } Complex operator / (const double &x) const { return (Complex){a/x,b/x}; } }f[maxn],g[maxn],w[maxn]; vector<int> to[maxn]; int size[maxn],val[maxn],vis[maxn],cnt[maxn],c1[maxn],tot[maxn],rev[maxn], n; int inc(int x,int y) { x+=y; return x>=p?x-p:x; } int dec(int x,int y) { x-=y; return x<0?x+p:x; } int pow(int b,int k) { int ret=1; for (;k;k>>=1,b=(LL)b*b%p) if (k&1) ret=(LL)ret*b%p; return ret; } int dfs2(int u,int fa,int S) { int ret=-1,v; size[u]=1; val[u]=0; for (vector<int>::iterator it=to[u].begin();it!=to[u].end();++it) if (!vis[*it]&&*it!=fa) { v=dfs2(*it,u,S); if (ret==-1||val[v]<val[ret]) ret=v; size[u]+=size[*it]; val[u]=max(val[u],size[*it]); } val[u]=max(val[u],S-size[u]); if (ret==-1||val[u]<val[ret]) ret=u; return ret; } void dfs3(int u,int fa) { size[u]=1; for (vector<int>::iterator it=to[u].begin();it!=to[u].end();++it) if (!vis[*it]&&*it!=fa) { dfs3(*it,u); size[u]+=size[*it]; } } int dfs4(int u,int fa,int d) { int ret=d; c1[d]++; for (vector<int>::iterator it=to[u].begin();it!=to[u].end();++it) if (!vis[*it]&&*it!=fa) ret=max(ret,dfs4(*it,u,d+1)); return ret; } void fft(Complex *a,int m,int t,int flag) { int x; Complex t1,t2; for (int i=0;i<m;i++) if (rev[i]>i) swap(a[i],a[rev[i]]); for (int i=0;i<t;i++) for (int j=0;j<m;j+=1<<(i+1)) { x=0; for (int k=j;k<j+(1<<i);k++) { t1=a[k]; t2=a[k+(1<<i)]*w[x]; a[k]=t1+t2; a[k+(1<<i)]=t1-t2; x+=flag*(1<<(t-i-1)); if (x<0) x+=m; } } if (flag==-1) for (int i=0;i<m;i++) a[i]=a[i]/m; } void dfs1(int u,int S) { int mx=0,m1,l,t,r; for (int i=1;i<=S;i++) cnt[i]=0; cnt[0]=1; r=dfs2(u,-1,S); vis[r]=1; dfs3(r,-1); for (vector<int>::iterator it=to[r].begin();it!=to[r].end();++it) if (!vis[*it]) { for (int i=0;i<=size[*it];i++) c1[i]=0; m1=dfs4(*it,r,1); l=1,t=0; while (l<=2*m1) l<<=1,t++; for (int i=0;i<=m1;i++) f[i]=(Complex){(double)c1[i],0.0}; for (int i=m1+1;i<l;i++) f[i]=(Complex){0,0}; for (int i=0;i<l;i++) w[i]=(Complex){cos(2*pi*i/l),sin(2*pi*i/l)}; for (int i=0;i<l;i++) { rev[i]=0; for (int j=0;j<t;j++) rev[i]|=((i>>j)&1)<<(t-j-1); } fft(f,l,t,1); for (int i=0;i<l;i++) f[i]=f[i]*f[i]; fft(f,l,t,-1); for (int i=0;i<l;i++) tot[i]=dec(tot[i],((LL)(f[i].a+0.5))%p); for (int i=0;i<=m1;i++) cnt[i]+=c1[i]; mx=max(mx,m1); } l=1,t=0; while (l<=2*mx) l<<=1,t++; for (int i=0;i<=mx;i++) f[i]=(Complex){(double)cnt[i],0.0}; for (int i=mx+1;i<l;i++) f[i]=(Complex){0,0}; for (int i=0;i<l;i++) w[i]=(Complex){cos(2*pi*i/l),sin(2*pi*i/l)}; for (int i=0;i<l;i++) { rev[i]=0; for (int j=0;j<t;j++) rev[i]|=((i>>j)&1)<<(t-j-1); } fft(f,l,t,1); for (int i=0;i<l;i++) f[i]=f[i]*f[i]; fft(f,l,t,-1); for (int i=0;i<l;i++) tot[i]=inc(tot[i],((LL)(f[i].a+0.5))%p); for (vector<int>::iterator it=to[r].begin();it!=to[r].end();++it) if (!vis[*it]) dfs1(*it,size[*it]); } int main() { //freopen("g.in","r",stdin); int ans=0,x,y; scanf("%d",&n); for (int i=1;i<n;i++) { scanf("%d%d",&x,&y); to[x].push_back(y); to[y].push_back(x); } dfs1(1,n); for (int i=0;i<n;i++) ans=inc(ans,(LL)tot[i]*pow(i+1,p-2)%p); for (int i=2;i<=n;i++) ans=(LL)ans*i%p; printf("%d\n",ans); }
相关文章推荐
- CodeForcesGym 100212E Long Dominoes
- codeforces gym 100357 I (费用流)
- CodeForcesGym 100733D Little thief Shi
- Codeforces Gym 221682 R Straight Shot(二分)
- Codeforces Gym 101201G Maximum Islands (dfs求联通块+最大独立集)
- Codeforces Gym 100548F Color (组合数+容斥)
- CodeForces Gym 100989J Objects Panel (A)
- Codeforces Gym 101190 (NEERC 2016) H. Hard Refactoring (模拟 + 树状数组)
- Codeforces Gym 101142 K. King's Heir
- CodeForces Gym 100735E
- Codeforces Gym 101164 G. Pokemons
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
- Codeforces Gym 101174 K. Balls and Needles (DFS)
- codeforces Gym 100187B B. A Lot of Joy
- Codeforces Gym 100825 F. Transportation Delegation (最大流)
- Codeforces Gym 101061B RGB plants
- Codeforces Rating Gym-101028A
- Codeforces Gym 100269E Energy Tycoon 贪心
- CodeForces Gym 100500A A. Poetry Challenge DFS
- Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest(二月十日训练赛)