Codechef Chef Cuts Tree

The SoftBrands SoftBrands when he in the end, when the routine is no longer a question of routine

First, we will link the size of the square blocks and transformed, it is found that equivalent communication point number , and this may be converted to the connection points of the number of edges (distance) and

Therefore, we consider the first \ (I \) days, a point \ ((x, y) \ ) can produce contribute if and only if a connection did not break their edges, so that the contribution of:

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

So we find this thing all the same distance from the point of is the same, so we can count directly all of the distance \ (i (i \ in [ 0, n-1]) \) points to the number \ (num_i \)

For one day and then consider \ (I \) enumeration distance \ (D \) of points, then:

\[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)!}\]

Apparently in the form of a convolution, we let \ (A (X) = (Ni-. 1)! \ Times num_i, B (X) = \ {I}. 1 FRAC {!} \) , Do not take back after convolution variables can then reverse

So there are two issues remaining, distance \ (i \) points to the number of how demand?

First, a point of divide and conquer , then there is a very naive idea is to traverse the violence after every single sub-tree information FFT Merge

But this encounter chrysanthemum map directly GG, so we can inclusion and exclusion at

In the center of each partition as a root path to find the number of pieces of all lengths and then subtracting repeated in the same sub-portion to the tree, and the method of calculating the square before the same convolution

One last question, NTT modulus than the modulusCancer of the topic and people, Do we write three-mode NTT ?

However, before the discovery of FFT has written, so we direct the demolition coefficient doing just fine

PS: I am not too weak MTT , so he wrote four DFT most violent, large constant IDFT version 4, the complexity of it as two \ (\ log \) view it

Finally ran 1.36s, pay attention to open long longandlong 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;
}

Guess you like

Origin www.cnblogs.com/cjjsb/p/11285742.html