[CF724F] Uniformly Branched Trees

链接

题目大意

求由 n 个节点构成且节点度数只为 1d 的本质不同无根树数量。

n1000,d10

题解

这个数据范围一看就很 O(n2d)O(n2d2)

首先假设这是一颗有根树。考虑dp,令 fi,j,k 表示 i 个节点的树中,根有 j 个儿子,其余节点有 d 个儿子。其中所有儿子大小不超过 k

对于有根树来说,同构相当于存在一种子树的对应关系。可以简单认为就是把子树按一定的顺序排序,然后一一对应。

大小显然可以作为第一维排序。所以我们把大小为 k 的儿子全部找出来,不妨假设有 t 个,那么剩下的状态就是 fitk,jt,k1

考虑转移过程的系数是多少。首先我们知道大小为 k 的本质不同合法子树数量是 fk,d1,k1。注意当 k=0 时应当特判,此时一定只有1种方案。

可以发现这样等同于“有 t 个相同小球,放进 fk,d1,k1 个不同的盒子中的方案数”,这个就是经典的隔板法,方案数为 (fk,d1,k1+t1t)

所以得到递推方程:fi,j,k=tfitk,jt,k1×(fk,d1,k1+t1t)。注意特判 t=0 时右边式子应当为1。

最后考虑同构怎么处理:首先我们应当钦定一个点为根,这里显然选重心最方便,因为重心的dp值对应就是 fn,d,n2

n 为奇数时这个dp值一定正确,因为一棵树的重心只有一个,不会记重。

但是当 n 为偶数时会有计重,因为这时一棵树的重心有两个。即如果我们钦定其中一个为根,那么两个重心之间的同构会被忽略。

但是可以发现,如果我们将两个重心之间的边断掉,一定会形成两个 n2 大小的树。这种情况下,如果两个树不棵构,交换两棵树就是另一种方案。

所以有两个重心且两棵树不互相同构的方案数为 n×(n1),所以最后方案数应减去 n(n1)2

复杂度 O(n2d2)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1010
#define D 12
using namespace std;
int fac[N],inv[N],mod;
int ksm(int a,int b=mod-2)
{
    int r=1;
    for(;b;b>>=1)
    {
        if(b&1) r=1ll*r*a%mod;
        a=1ll*a*a%mod;
    }
    return r;
}
int C(int a,int b)
{
    int r=inv[b];
    for(b--;b>=0;b--) r=1ll*r*(a-b)%mod;
    return r;
}
int f[N][D][N];
int main()
{
    int n,d;
    scanf("%d%d%d",&n,&d,&mod);
    if(n<=2){puts("1");return 0;}
    fac[0]=1;
    for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
    inv[n]=ksm(fac[n]);
    for(int i=n-1;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
    for(int i=0;i<=n;i++) f[1][0][i]=1;
    for(int i=2;i<=n;i++)
        for(int j=1;j<=min(d,i-1);j++)
            for(int k=1;k<=n;k++)
            {
                f[i][j][k]=f[i][j][k-1];
                for(int t=1;t*k<=i && t<=j;t++)
                f[i][j][k]=(f[i][j][k]+1ll*f[i-t*k][j-t][k-1]*(k==1?1:C(f[k][d-1][k-1]+t-1,t))%mod)%mod;
            }
    printf("%d\n",(f[n][d][n/2]-((n&1)?0:C(f[n/2][d-1][n/2-1],2))+mod)%mod);
    return 0;
}
posted @   Flying2018  阅读(91)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示