2020牛客暑期多校训练营(第七场) Valuable Forests

原题
题目描述
2020牛客暑期多校训练营(第七场) Valuable Forests_第1张图片
样例
输入

5 1000000007
2
3
4
5
107

输出

2
24
264
3240
736935633

思路
以下是乍一眼看不懂的官方题解:
2020牛客暑期多校训练营(第七场) Valuable Forests_第2张图片
这种规律过于玄学,所以我们找到了另一种解题思路:
因为要用到 p r u f e r prufer prufer序列,所以大家可以参考一下这篇博客。

  • 因为n个点的无根树可以形成nn−2个不同的树,所以我们不妨设它的值为 d p n dp_n dpn ,设n个点的森林个数为 f n f_n fn。在第n个点加入时,我们可以选择 i i i个点和它形成一棵树,那么就可以列出 d p dp dp式:
    d p n = ∑ i = 0 n − 1 C n − 1 i f ( n − i − 1 ) b i + 1 dp_n=\sum_{i=0}^{n-1}C_{n-1}^if(n-i-1)b_{i+1} dpn=i=0n1Cn1if(ni1)bi+1
  • 然后我们可以再定义一个n个点能形成的所有无根树的权值和为 a n a_n an,并枚举它的度数为 i i i,列出 d p dp dp式:
    a n = n ∑ i = 1 n − 1 a_n=n\sum_{i=1}^{n-1} an=ni=1n1 i i i2 C n − 2 i − 1 C_{n-2}^{i-1} Cn2i1 ( n − 1 ) (n-1) (n1)(n-1-d)
  • 最后我们定义 a n s n ans_n ansn为答案,列出 d p dp dp式:
    a n s n = ∑ i = 0 n − 1 ans_n=\sum_{i=0}^{n-1} ansn=i=0n1 C n − 1 i C_{n-1}^{i} Cn1i* ( ( ( b i + 1 ∗ a n s n − i − 1 + d p n − i − 1 ∗ a i + 1 ) b_{i+1}*ans_{n-i-1}+dp_{n-i-1}*a_{i+1}) bi+1ansni1+dpni1ai+1)
    我们只要根据以上公式打表即可,具体细节可以看看代码。
    代码
#include
using namespace std;
#define ll long long
const int maxn=5010;
ll t,n,mod,c[maxn][maxn],f[maxn],p[maxn],dp[maxn],ans[maxn];
int ksm(ll a,ll b)//这里要开long long,快速幂加快运算
{
    if(b<=0)return 1;
    ll k=1;
    while(b)
    {
        if(b&1)k=k*a%mod;
        b>>=1;a=(a*a)%mod;
    }
    return k;
}
int main()
{
    scanf("%lld%lld",&t,&mod);c[0][0]=f[0]=f[1]=p[0]=p[1]=1;
    for(int i=1;i<=5000;i++)
    {
        c[0][i]=1;
        for(int j=1;j<=i;j++)c[j][i]=(c[j][i-1]+c[j-1][i-1])%mod;
    }
    for(int i=1;i<=5000;i++)
    {
        for(int j=1;j<i;j++)dp[i]=(j*j%mod*c[j-1][i-2]%mod*ksm(i-1,i-1-j)%mod+dp[i]%mod)%mod;
        dp[i]=i*dp[i]%mod;
        if(i^1)p[i]=ksm(i,i-2);
    }
    for(int i=2;i<=5000;i++)
        for(int j=0;j<i;j++)
            f[i]=(c[j][i-1]*f[i-j-1]%mod*p[j+1]%mod+f[i])%mod;
    for(int i=2;i<=5000;i++)
        for(int j=1;j<=i;j++)
            ans[i]=(c[j-1][i-1]*((p[j]*ans[i-j]%mod+f[i-j]*dp[j]%mod)%mod)+ans[i]%mod)%mod;
    while(t--)scanf("%lld",&n),printf("%lld\n",ans[n]);
    return 0;
}

你可能感兴趣的:(2020牛客暑期多校训练营(第七场) Valuable Forests)