题目

求\(n\)个点直径为\(d\)的标号树个数(多组数据)

(\(0\leq d\leq n\leq 50,n>0\))


分析

首先特判一下\(n==d\)无解,\(d=0\)除非只有一个点,\(d=1\)除非只有两个点

然后直径很难搞,考虑把它转换成深度

设\(dp[n][h]\)表示\(n\)个点,深度不超过\(h\)的标号树个数

那么\(dp[n][h]=\sum_{i=1}^{n-1}dp[i][h-1]*dp[n-i][h]*c[n-2][i-1]*i\)

解释一下什么意思,就是我钦定1号节点为\(n-i\)个点所组成的树中的根,

2号点在\(i\)个点所组成的树中,现在要把这两棵树合并,那么就要乘\(dp[i][h-1]*dp[n-i][h]\)另一棵树的根接到1下

然后在\(n-2\)个点中选择\(i-1\)个点,而且还要从\(i\)个点中选取一个作为子树的根

在标号树的dp中,通常以1号节点为根,枚举2号节点所在的子树,将该子树拼接在1号节点下

然后考虑怎么拼接了

如果直径长度是奇数,那么考虑把它分成两部分,这两部分通过一条边相连

也就是两部分的树高度都是\(h=d/2\)

断开那条边,先枚举两个子树的根就是\(C(n,2)\),

再在剩下\(n-2\)个点中拿出\(i-1\)个点放在一边,剩下的自然就放在另一边

那么\(ans=\sum_{i=h+1}^n\sum_{i+j=n,j>h}(dp[i][h]-dp[i][h-1])*(dp[j][h]-dp[j][h-1])*C(n-2,i-1)*C(n,2)\)

如果直径是偶数就比较麻烦了,如果直径为2,那就是一个菊花图

枚举根,就是\((dp[n][h]-dp[h-1])*n\)

但是如果直径超过2还要减去不合法的,

如图所示,虽然深度达到了\(h\)但是直径小于\(2h\)

那么枚举根,再枚举所要拼接的子树大小\(i\),还要从\(i\)个点内选择1个点作为根

那么答案就是\(c(n-1,i)*n*i*dp[n-i][h-1]*(dp[i][h-1]-dp[h-2])\)

把这些不合法的减去,记得高精度(进位不删掉,亲人两行泪)


代码

#include <cstdio>
#include <cstring>
#define rr register
const int mod=1000000000,N=51; long long c[N][N];
struct Big{long long p[11];}dp[N][N];
Big operator +(Big a,Big b){
rr int Len=a.p[0]>b.p[0]?a.p[0]:b.p[0],g=0;
rr Big c; memset(c.p,0,sizeof(c.p));
for (rr int i=1;i<=Len;++i){
c.p[i]=a.p[i]+b.p[i]+g;
if (c.p[i]>=mod) g=1,c.p[i]-=mod;
else g=0;
}
if (g) c.p[++Len]=g;
c.p[0]=Len;
return c;
}
Big operator -(Big a,Big b){
rr int Len=a.p[0]>b.p[0]?a.p[0]:b.p[0],g=0;
rr Big c; memset(c.p,0,sizeof(c.p));
for (rr int i=1;i<=Len;++i){
rr int s=a.p[i]-b.p[i]-g;
if (s<0) s+=mod,g=1; else g=0;
c.p[i]=s;
}
while (!c.p[Len]) --Len;
c.p[0]=Len;
return c;
}
Big operator *(Big a,Big b){
rr int Len=a.p[0]+b.p[0];
rr Big c; memset(c.p,0,sizeof(c.p));
for (int i=1;i<=a.p[0];++i)
for (int j=1;j<=b.p[0];++j)
c.p[i+j-1]+=a.p[i]*b.p[j];
for (rr int i=1;i<=Len;++i) c.p[i+1]+=c.p[i]/mod,c.p[i]%=mod;
if (!c.p[Len]) --Len;
c.p[0]=Len;
return c;
}
inline Big Num_To_Big(long long n){
rr Big c; memset(c.p,0,sizeof(c.p));
for (;n;n/=mod) c.p[++c.p[0]]=n%mod;
return c;
}
inline void zero_print(int ans){
for (rr int lim=mod/10;lim>1&&lim>ans;lim/=10) putchar(48);
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline void Big_print(Big ans){
print(ans.p[ans.p[0]]);
for (rr int i=ans.p[0]-1;i;--i)
zero_print(ans.p[i]),print(ans.p[i]);
}
signed main(){
c[0][0]=1;
for (rr int i=1;i<N;++i){
c[i][0]=c[i][i]=1;
for (rr int j=1;j<i;++j)
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
for (rr int i=0;i<N;++i) dp[1][i]=Num_To_Big(1);
for (rr int i=2;i<N;++i) dp[i][0]=Num_To_Big(0);
for (int n=2;n<N;++n)
for (int d=1;d<N;++d){
dp[n][d]=Num_To_Big(0);
if (d>=n) {dp[n][d]=dp[n][d-1]; continue;}
for (rr int i=1;i<n;++i)
dp[n][d]=dp[n][d]+Num_To_Big(c[n-2][i-1]*i)*dp[i][d-1]*dp[n-i][d];
}
for (rr int n,d;scanf("%d%d",&n,&d)==2;putchar(10)){
rr int h=d/2; rr Big ans=Num_To_Big(0);
if (n==d) {putchar(48); continue;}
if (!d) {putchar(48+(n==1)); continue;}
if (!h) {putchar(48+(n==2)); continue;}
if (d&1){
for (rr int i=h+1;i<=n;++i){
rr int j=n-i; if (j<=h) break;
ans=ans+(dp[i][h]-dp[i][h-1])*(dp[j][h]-dp[j][h-1])*Num_To_Big(c[n-2][i-1]*c[n][2]);
}
}else{
ans=(dp[n][h]-dp[n][h-1])*Num_To_Big(n);
if (h>=2){
for (rr int i=h;i<n;++i)
ans=ans-Num_To_Big(c[n-1][i]*n*i)*dp[n-i][h-1]*(dp[i][h-1]-dp[i][h-2]);
}
}
Big_print(ans);
}
return 0;
}

#高精度,排列组合、dp#JZOJ 2755 树的计数的更多相关文章

  1. [Bzoj3193][JLOI2013]地形生成 (排列组合 + DP)

    3193: [JLOI2013]地形生成 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 459  Solved: 223[Submit][Status ...

  2. nyoj1076-方案数量 【排列组合 dp】

    http://acm.nyist.net/JudgeOnline/problem.php?pid=1076 方案数量 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 ...

  3. 【noi 2.6_9288】&【hdu 1133】Buy the Ticket(DP / 排列组合 Catalan+高精度除法)

    题意:有m个人有一张50元的纸币,n个人有一张100元的纸币.他们要在一个原始存金为0元的售票处买一张50元的票,问一共有几种方案数. 解法:(学习了他人的推导后~) 1.Catalan数的应用7的变 ...

  4. ACdream 1412 DP+排列组合

    2-3 Trees Problem Description 2-3 tree is an elegant data structure invented by John Hopcroft. It is ...

  5. LightOJ1005 Rooks(DP/排列组合)

    题目是在n*n的棋盘上放k个车使其不互相攻击的方案数. 首先可以明确的是n*n最多只能合法地放n个车,即每一行都指派一个列去放车. dp[i][j]表示棋盘前i行总共放了j个车的方案数 dp[0][0 ...

  6. 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas

    [题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...

  7. 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值

    [题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...

  8. HDU 5816 状压DP&排列组合

    ---恢复内容开始--- Hearthstone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java ...

  9. 2017ACM暑期多校联合训练 - Team 8 1011 HDU 6143 Killer Names (容斥+排列组合,dp+整数快速幂)

    题目链接 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ...

  10. bzoj 3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛——前缀和优化dp / 排列组合

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 好简单呀.而且是自己想出来的. dp[ i ]表示最后一个牡牛在 i 的方案数. 当前 ...

随机推荐

  1. 2021-07-20 value!==value,JavaScript中NaN

    关于NaN NaN 属性代表一个"不是数字"的number类型的字面量值.这个特殊的值是因为运算不能执行而导致的,不能执行的原因要么是因为其中的运算对象之一非数字. NaN的出现场 ...

  2. channel管道

    channel 如果说goroutine是并发体的话,那么channels则是他们之间的通信机制.一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发生值 ...

  3. java基础字符串---02

    String 概述 String类在java.lang包下,所以使用的时候不需要导包 String类代表字符串,java程序中的所有字符串文字(例如"abc")都被实现为此类的实例 ...

  4. 【LeetCode排序专题01】由旋转数组的最小数字引出的关于排序算法的讨论(冒泡排序、二分查找+暴力法)

    旋转数组的最小数字 剑指 Offer 11. 旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一 ...

  5. 【Azure 应用服务】App Service 默认页面暴露Tomcat版本信息,存在安全风险

    问题描述 在创建Azure App Service时,服务端的配置使用Java 8 + Tomcat 8.5.默认的根目录页面显示出App Service Tomcat版本信息,存在一定的安全隐患. ...

  6. 【Azure 应用服务】Azure Web App 服务默认支持一些 Weak TLS Ciphers Suite,是否有办法自定义修改呢?

    问题描述 当 Azure Web App 进行安全扫描后,发现依旧支持很多弱TLS加密套件(Weak TLS Ciphers Suite),那么是否有办法来关闭这些弱的加密套件呢? 在Windows ...

  7. 深入解析ASP.NET Core MVC应用的模块化设计[上篇]

    ASP.NET Core MVC的"模块化"设计使我们可以构成应用的基本单元Controller定义在任意的模块(程序集)中,并在运行时动态加载和卸载.这种为"飞行中的飞 ...

  8. 1. JVM体系结构

    1. 前言 作为Java工程师 ,jvm对于 java的重要性不言而喻,但是 我们又对jvm了解多少 Java的跨平台性 java发布的口号 "一处编译到处运行 " 依赖于jvm, ...

  9. mysql标识列和事务

    1 #标识列 2 /* 3 又称为自增长列 4 含义:可以不用手动的插入值,系统提供默认的序列值 5 6 7 特点: 8 1.标识列必须和主键搭配吗?不一定,但要求是一个key 9 2.一个表可以有几 ...

  10. 2FA双因素认证 - 原理和应用

    主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 引言 我们在登陆网站.或者通过VPN访问公司内网时,除了输入用户口令外 ...