• 牛客 Valuable Forest(XJOJ4 F森林)


    Description

    一棵树的 F 值是所有点的度数的平方和,

    一个森林的 F 值是森林里所有树的 F 值的和。

    求所有 n 个点的森林的 F 值的和 (有标号,树都是无根树)。

    Solution

    prufer序列:n个点的无根树共有$n^{n-2}$种
    令$f(n)$为有n个点的森林的个数
    $$f(n)=sum_{i=0}^{n-1} C_{n-1}^i f(n-i-1)(i+1)^{i-1}$$
    意思是加入第n个点时,在原来的n-1个点中选择i个点与其连成一棵树
    令$A(n)$为n个点的所有无根树中的权值之和
    $$A(n)=n sum_{d=1}^{n-1}d^2 C_{n-2}^{d-1} (n-1)^{n-d-1}$$
    意思是对于每一个点枚举度数d,统计其在prufer序列中仅出现d-1次的方案数
    令$F(n)$记录答案
    $$F(n)=sum_{i=0}^{n-1} C_{n-1}^{i} [(i+1)^{i-1}F(n-i-1)+f(n-i-1)A(i+1)]$$
    意思是在加入第n个点时,在原来的n-1个点中选择i个点与其形成一棵树,答案为这样的树的总个数乘对应的权值和 + 其余的n-i-1个点形成森林的个数乘方案数

    #pragma GCC optimize(2)
    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long C[5005][5005],T,mod,A[5005],F[5005],f[5005],st[5005],n,qp[5005][5005];
    inline long long read()
    {
        long long f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return f*w;
    }
    long long ksm(long long a,long long p)
    {
        long long ret=1ll;
        while(p)
        {
            if(p&1)
            {
                (ret*=a)%=mod;
            }
            (a*=a)%=mod;
            p>>=1;
        }
        return ret;
    }
    int main()
    {
        T=read(),mod=read();
        for(int i=1;i<=5000;i++)
        {
            qp[i][0]=1ll;
            for(int j=1;j<=5000;j++)
            {
                qp[i][j]=qp[i][j-1]*i%mod;
            }
        }
        C[0][0]=1ll;
        for(long long i=1;i<=5000;i++)
        {
            C[i][0]=1ll;
            for(long long j=1;j<=i;j++)
            {
                C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
            }
        }
        st[0]=st[1]=1ll;
        for(int i=2;i<=5000;i++)
        {
            st[i]=ksm(i,i-2);
        }
        f[0]=f[1]=1ll;
        for(long long i=2;i<=5000;i++)
        {
            for(long long j=0;j<=i-1;j++)
            {
                (f[i]+=C[i-1][j]*f[i-1-j]%mod*st[j+1]%mod)%=mod;
            }
        }
        for(long long i=2;i<=5000;i++)
        {
            for(long long d=1;d<=i-1;d++)
            {
                (A[i]+=d*d%mod*C[i-2][d-1]%mod*qp[i-1][i-2-d+1]%mod)%=mod;
            }
            (A[i]*=i)%=mod;
        }
        for(long long i=2;i<=5000;i++)
        {
            for(long long j=0;j<=i-1;j++)
            {
                (F[i]+=C[i-1][j]*(st[j+1]*F[i-1-j]%mod+f[i-j-1]*A[j+1]%mod)%mod)%=mod;
            }
        }
        for(;T;T--)
        {
            n=read();
            printf("%lld
    ",F[n]);
        }
        return 0;
    }
    Valuable Forest
  • 相关阅读:
    解说asp.net core MVC 过滤器的执行顺序
    asp.net core 2.0 Microsoft.Extensions.Logging 文本文件日志扩展
    【技术累积】【点】【java】【30】代理模式
    【技术累积】【点】【java】【29】MapUtils
    【技术累积】【点】【java】【28】Map遍历
    【技术累积】【点】【java】【27】@JSONField
    【技术累积】【点】【java】【26】@Value默认值
    【技术累积】【点】【java】【25】Orderd
    【技术累积】【点】【java】【23】super以及重写重载
    【技术累积】【线】【java】【2】AOP
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13425906.html
Copyright © 2020-2023  润新知