该思博的时候就思博到底,套路的时候不能再套路的一道题

首先我们将联通块的大小平方和进行转化,发现它就等价于连通点对数,而这个可以转化为连接两点的边数(距离)和

所以我们考虑第\(i\)天时,一个点对\((x,y)\)能产生贡献,当且仅当连接它们的边一条都没断,故贡献为:

\[\frac{(n-1-\operatorname{dis}(x,y))^{\underline i}}{(n-1)^{\underline i}}
\]

因此我们发现这个东西对于所有距离相同的点对是一样的,因此我们可以直接统计出所有的距离为\(i(i\in[0,n-1])\)的点对数\(num_i\)

然后考虑对于一天\(i\)枚举距离为\(d\)的点对,则:

\[ans_i=\sum_{d=0}^{n-1}\frac{(n-d-1)!\times(n-i-1)!\times num_d}{(n-d-i-1)!\times(n-1)!}
\]

显然是一个卷积的形式,我们令\(A(x)=(n-i-1)!\times num_i,B(x)=\frac{1}{i!}\),卷积之后乘回不变项然后反转即可

那么剩下还有两个问题,距离为\(i\)的点对数怎么求?

首先一眼点分治,然后有一个很naive的想法就是遍历每颗子树信息后暴力FFT合并

但这样遇到菊花图就直接GG了,因此我们可以容斥一下

每次以分治中心为根找出所有长度的路径条数,然后卷积平方后减去重复在同一子树内的部分即可,计算方法和之前一致

最后一个问题,模数不是NTT模数毒瘤出题人,难不成我们写三模NTT

然而发现之前FFT已经写好了,因此我们直接拆系数做就好了

PS:本人太弱不会MTT,因此写了最暴力的4次DFT,4次IDFT的大常数版本,复杂度就当作两只\(\log\)来看吧

最后跑了1.36s,注意开long longlong double

CODE

#include<cstdio>
#include<cctype>
#include<iostream>
#include<cmath>
#define int LL
#define RI register int
#define CI const int&
#define Tp template <typename T>
#define CC const Complex&
using namespace std;
typedef long long LL;
const int N=200005,INF=1e9,mod=1e9+7;
const long double pi=acos(-1);
class FileInputOutput
{
private:
static const int S=1<<21;
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
#define pc(ch) (Ftop!=Fend?*Ftop++=ch:(fwrite(Fout,1,S,stdout),*(Ftop=Fout)++=ch))
char Fin[S],Fout[S],*A,*B,*Ftop,*Fend; int pt[15];
public:
inline FileInputOutput() { Ftop=Fout; Fend=Fout+S; }
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
Tp inline void write(T x)
{
RI ptop=0; while (pt[++ptop]=x%10,x/=10);
while (ptop) pc(pt[ptop--]+48); pc(' ');
}
inline void flush(void)
{
fwrite(Fout,1,Ftop-Fout,stdout);
}
#undef tc
#undef pc
}F;
struct Complex
{
long double x,y;
inline Complex(const long double& X=0,const long double& Y=0)
{
x=X; y=Y;
}
friend inline Complex operator + (CC A,CC B)
{
return Complex(A.x+B.x,A.y+B.y);
}
friend inline Complex operator - (CC A,CC B)
{
return Complex(A.x-B.x,A.y-B.y);
}
friend inline Complex operator * (CC A,CC B)
{
return Complex(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x);
}
inline void operator /= (const long double& p)
{
x/=p; y/=p;
}
}A[N<<2]; int a[N<<2],ans[N<<2],fact[N],inv[N];
struct edge
{
int to,nxt;
}e[N<<1]; int n,head[N],cnt,x,y,dis[N],lim;
class FFT_Solver
{
private:
static const int S=ceil(sqrt(mod)),SS=1LL*S*S%mod;
int rev[N<<2],p;
public:
inline void init(CI n)
{
for (lim=1,p=0;lim<=n;lim<<=1,++p);
for (RI i=0;i<lim;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<p-1);
}
inline void FFT(Complex *f,CI opt)
{
RI i; for (i=0;i<lim;++i) if (i<rev[i]) swap(f[i],f[rev[i]]);
for (i=1;i<lim;i<<=1)
{
Complex D(cos(pi/i),sin(pi/i)*opt);
for (RI j=0;j<lim;j+=(i<<1))
{
Complex W(1,0); for (RI k=0;k<i;++k,W=W*D)
{
Complex x=f[j+k],y=f[i+j+k]*W;
f[j+k]=x+y; f[i+j+k]=x-y;
}
}
}
if (!~opt) for (i=0;i<lim;++i) f[i]/=lim;
}
inline void MTT(int *TA,int *TB,int *TC,CI n)
{
static Complex A[N<<2],B[N<<2],C[N<<2],D[N<<2],E[N<<2],F[N<<2],G[N<<2],H[N<<2];
RI i; for (init(n<<1),i=0;i<n;++i)
A[i]=Complex(TA[i]/S),B[i]=Complex(TA[i]%S),C[i]=Complex(TB[i]/S),D[i]=Complex(TB[i]%S);
for (FFT(A,1),FFT(B,1),FFT(C,1),FFT(D,1),i=0;i<lim;++i)
E[i]=A[i]*C[i],F[i]=B[i]*C[i],G[i]=A[i]*D[i],H[i]=B[i]*D[i];
for (FFT(E,-1),FFT(F,-1),FFT(G,-1),FFT(H,-1),i=0;i<lim;++i)
TC[i]=(((LL)(E[i].x+0.5)%mod)*SS)%mod,(TC[i]+=(((LL)(F[i].x+0.5)%mod)*S)%mod)%=mod,
(TC[i]+=(((LL)(G[i].x+0.5)%mod)*S)%mod)%=mod,(TC[i]+=(LL)(H[i].x+0.5)%mod)%=mod;
}
}P;
#define to e[i].to
class Point_Divide_Solver
{
private:
int size[N],mx[N],num[N],rt,ats,mdp; bool vis[N];
inline void maxer(int& x,CI y)
{
if (y>x) x=y;
}
inline void getrt(CI now=1,CI fa=0)
{
size[now]=1; mx[now]=0; for (RI i=head[now];i;i=e[i].nxt)
if (to!=fa&&!vis[to]) getrt(to,now),size[now]+=size[to],maxer(mx[now],size[to]);
if (maxer(mx[now],ats-size[now]),mx[now]<mx[rt]) rt=now;
}
inline void travel(CI now,CI fa=0,CI dep=0)
{
maxer(mdp,dep); ++num[dep]; for (RI i=head[now];i;i=e[i].nxt)
if (to!=fa&&!vis[to]) travel(to,now,dep+1);
}
inline void calc(CI opt)
{
RI i; for (P.init(mdp<<1),i=0;i<=mdp;++i) A[i]=Complex(num[i],0);
for (i=mdp+1;i<lim;++i) A[i]=Complex();
for (P.FFT(A,1),i=0;i<lim;++i) A[i]=A[i]*A[i];
for (P.FFT(A,-1),lim=min(n-1,mdp<<1),i=0;i<=lim;++i)
dis[i]+=(LL)(A[i].x+0.5)%mod*opt,(dis[i]+=mod)%=mod;
}
inline void clear(void)
{
for (RI i=0;i<=mdp;++i) num[i]=0;
}
inline void solve(CI now)
{
RI i; mdp=0; travel(now); calc(1); clear(); vis[now]=1;
for (i=head[now];i;i=e[i].nxt) if (!vis[to])
mdp=0,travel(to,now,1),calc(-1),clear();
for (i=head[now];i;i=e[i].nxt) if (!vis[to])
mx[rt=0]=INF,ats=size[to],getrt(to,now),solve(rt);
}
public:
inline void divide(void)
{
mx[rt=0]=INF; ats=n; getrt(); solve(rt);
}
}PD;
#undef to
inline void addedge(CI x,CI y)
{
e[++cnt]=(edge){y,head[x]}; head[x]=cnt;
e[++cnt]=(edge){x,head[y]}; head[y]=cnt;
}
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline void init(void)
{
RI i; for (fact[0]=i=1;i<=n;++i) fact[i]=1LL*fact[i-1]*i%mod;
for (inv[n]=quick_pow(fact[n]),i=n-1;~i;--i) inv[i]=1LL*inv[i+1]*(i+1)%mod;
for (i=0;i<n;++i) a[i]=1LL*fact[n-i-1]*dis[i]%mod;
//for (i=0;i<n;++i) printf("%d ",a[i]); putchar('\n');
//for (i=0;i<n;++i) printf("%d ",inv[i]); putchar('\n');
}
signed main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (F.read(n),i=1;i<n;++i) F.read(x),F.read(y),addedge(x,y);
for (PD.divide(),init(),P.MTT(a,inv,ans,n),i=0;i<n;++i)
ans[n-i-1]=1LL*ans[n-i-1]*inv[n-1]%mod*fact[n-i-1]%mod;
for (i=0;i<n;++i) F.write(ans[n-i-1]); return F.flush(),0;
}

Codechef Chef Cuts Tree的更多相关文章

  1. Codechef Union on Tree

    Codechef Union on Tree https://www.codechef.com/problems/BTREE 简要题意: 给你一棵树,\(Q\)次询问,每次给出一个点集和每个点的\(r ...

  2. CodeChef:Chef and Problems(分块)

    CodeChef:Chef and Problems 题目大意 有一个长度为n的序列$a_1,a_2,……,a_n$,每次给出一个区间[l,r],求在区间内两个相等的数的最远距离($max(j-i,满 ...

  3. Codechef Observing the Tree

    Home » Practice(Hard) » Observing the Tree   https://www.codechef.com/problems/QUERY Observing the T ...

  4. CODECHEF Chef and Churus 解题报告

    [CODECHEF]Chef and Churus Description 有一个长度为\(n\)的数组\(A\),有\(n\)个函数,第\(i\)个函数的值为\(\sum_{j=l_i}^{r_i} ...

  5. codechef Chef and The Right Triangles 题解

    Chef and The Right Triangles The Chef is given a list of N triangles. Each triangle is identfied by ...

  6. Codechef Chef and Triangles(离散化+区间并集)

    题目链接 Chef and Triangles 先排序,然后得到$m - 1$个区间: $(a[2] - a[1], a[2] + a[1])$ $(a[3] - a[2], a[3] + a[2]) ...

  7. CodeChef Chef and Churu [分块]

    题意: 单点修改$a$ 询问$a$的区间和$f$的区间和 原来普通计算机是这道题改编的吧... 对$f$分块,预处理$c[i][j]$为块i中$a_j$出现几次,$O(NH(N))$,只要每个块差分加 ...

  8. codechef Chef And Easy Xor Queries

    做法:我们考虑前缀异或和,修改操作就变成了区间[i,n]都异或x 查询操作就变成了:区间[1,x]中有几个k 显然的分块,每个块打一个tag标记表示这个块中所有的元素都异或了tag[x] 然后处理出这 ...

  9. 2019.02.14 codechef Chef at the Food Fair(线段树+泰勒展开)

    传送门 题意:现在有nnn个位置,每个位置上有一个值aia_iai​. 要求支持如下两种操作: 区间乘vvv 求区间的(1−ai)(1-a_i)(1−ai​)之积 思路: 考虑转换式子: Ans=∏i ...

随机推荐

  1. 针对.NET Core, Xamarin以及.NET的自动类型安全Rest库: Refit

    本文大部分内容是针对Refit官网的翻译. 官网地址: https://github.com/reactiveui/refit Refit是一个类似于Retrofit的Restful Api库,使用它 ...

  2. Java的POJO和JavaBean的区别

    POJO Plain Ordinary Java Object,即简单的java对象. 特点 需要有一些 private 的参数,以及针对参数的 setter 和 getter 方法来访问这些参数. ...

  3. java架构之路(多线程)JMM和volatile关键字

    说到JMM大家一定很陌生,被我们所熟知的一定是jvm虚拟机,而我们今天讲的JMM和JVM虚拟机没有半毛钱关系,千万不要把JMM的任何事情联想到JVM,把JMM当做一个完全新的事物去理解和认识. 我们先 ...

  4. RFC的远程调用-异步

    接上篇RFC的远程调用-同步(https://www.cnblogs.com/BruceKing/p/11169930.html). TABLES:USR21. DATA:A TYPE USR21-P ...

  5. C#调用Activex中串口电子秤的数据,并将电子秤的数据显示到前端页面

    大二的一个项目需要用到Activex技术将读取到串口中的数据在后台获取到,并将串口的数据写入数据库,这个过程需要在后台使用C#调用Activex控件已经使用的方法,然后在前端通过JavaScript进 ...

  6. C#编辑xml文件

    string path = @"C:\Users\Administrator\Desktop\无人智能便利店\install\收银端\XMLRFI.xml"; XmlDocumen ...

  7. 剑指 Offer——13. 调整数组顺序使奇数位于偶数前面

    题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变.这和书本不太一样. 解 ...

  8. Python脚本1

    [轮子]P123. 求最大约数,并鉴别是否为素数

  9. Jquery选择器与样式操作

    jquery选择器 jquery用法思想一 选择某个网页元素,然后对它进行某种操作 jquery选择器 jquery选择器可以快速地选择元素,选择规则和css样式相同,使用length属性判断是否选择 ...

  10. jsTree树插件

    前言 关于树的数据展示,前后用过两个插件,一是zTree,二是jsTree,无论是提供的例子(可下载),还是提供的API在查找时的便捷程度,zTree比jsTree强多了,也很容易上手,所以这里只讲下 ...