1 条题解
-
0
自动搬运
来自洛谷,原作者为

Umbrella_Leaf
曹刘生子,当如孙仲谋。搬运于
2025-08-24 22:38:04,当前版本为作者最后更新于2022-05-06 21:17:53,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
分析
设 表示第一棵树的非叶子集合恰好为 时构造第一棵树的方案数。
设 表示第二棵树的非叶子集合恰好为 时构造第二棵树的方案数。
那么答案为
$$Ans=\sum_{S\cap T=\varnothing,S\cup T=\{1,2,\cdots,n\}}f(S)g(T) $$直接求这个不太好求,我们考虑容斥。
$$\begin{aligned} Ans&=\sum_{S\cap T=\varnothing,S\cup T=\{1,2,\cdots,n\}}f(S)g(T)\\&=\sum_{S\cap T=\varnothing,S\cup T=\{1,2,\cdots,n\}}\sum_{S'\subseteq S,T'\subseteq T}f'(S')g'(T')(-1)^{|S|-|S'|+|T|-|T'|} \\&=\sum_{S'\cap T'=\varnothing}f'(S')g'(T')(-1)^{n-|S'|-|T'|}2^{n-|S'|-|T'|}\\&=\sum_{S'\cap T'=\varnothing}f'(S')g'(T')(-2)^{n-|S'|-|T'|} \end{aligned} $$设 表示第一棵树的非叶子集合包含于 时构造第一棵树的方案数。
设 表示第二棵树的非叶子集合包含于 时构造第二棵树的方案数。
其中倒数第二个等号的理由是:不属于 和 的那些元素可能在 中,也可能在 中。
然后可以 DP,我们设 表示确定了 中的点在 和 中的情况,, ,且我们已经为 选好了第一棵树中的父亲,为 选好了第二棵树中的父亲时,这些父亲的方案数。
初值:,。因为 一定是第一棵树的非叶子节点,也一定是第二棵树的叶子节点,不需要对其进行容斥。
转移时,分类讨论 在 和 中的情况,然后确定 在第一棵树中的父亲和 在第二棵树中的父亲:
- 属于 , 转移到 ,系数为
- 属于 , 转移到 ,系数为
- 两个都不属于, 转移到 ,系数为
其中转移系数中包含 的原因是:
考虑对于一个 ,如何计算 。
对于节点 , 可能是 中的任意一个非叶子节点下面,那么方案数是 中非叶子节点的个数,也就是 。
同理,只不过此时我们计算的是 在第二棵树中的父亲方案数,也就是 中非叶子节点的个数。
根据乘法原理,只需要将所有这样的点个数乘起来即可。
代码
#include<bits/stdc++.h> using namespace std; #define ll long long int n;ll mod; ll dp[2][505][505]; int main(){ scanf("%d%lld",&n,&mod); for(int i=1;i<n;i++)dp[1][1][i]=1; for(int i=2,now=0;i<=n;i++,now^=1){ memset(dp[now],0,sizeof(dp[now])); ll ans=0; for(int j=1;j<i;j++) for(int k=1;k<=n-i+1;k++)if(dp[now^1][j][k]){ dp[now][j][k]=(dp[now][j][k]+dp[now^1][j][k]*(mod-2)%mod*j%mod*k%mod)%mod; dp[now][j+1][k]=(dp[now][j+1][k]+dp[now^1][j][k]*j%mod*k%mod)%mod; dp[now][j][k-1]=(dp[now][j][k-1]+dp[now^1][j][k]*j%mod*k%mod)%mod; if(k==1)ans=(ans+dp[now^1][j][k]*j%mod*k%mod)%mod; } printf("%lld\n",ans); } return 0; }
- 1
信息
- ID
- 7652
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者