题目

求\(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. Mybatis-Plus自动生成代码的CodeGenerator代码

    官方地址:Mybatis-Plus:https://mp.baomidou.com/guide/generator.html pom中导入mybatis plus的jar包,因为后面会涉及到代码生成, ...

  2. 格式化占位符%r和!r

    # 作用 都是格式化原形输出,!r用于format格式化,%r用于%格式化 # 示例 a = '123' b = 'hello, {!r}'.format(a) b = 'hello, %r' % ( ...

  3. HTML学习---day01

    1.head标签 <!DOCTYPE html> <!--文档声明H5 html--> <html lang="en"> <head> ...

  4. linux下安装django2.2

    安装 pip3 install django==2.2 创建项目 django-admin startproject pyweb 创建应用 django-admin startapp app01 修改 ...

  5. java+mysql学生信息管理系统

    实现:mysql+eclipse(idea设置之后也可运行)+jdk8 功能: 管理员:管理登+管理员注册 学生:添加学生信息+删除学生信息+修改学生信息+查询学生信息+学生列表展示 界面展示: 详情 ...

  6. 常用 Maven 插件介绍

    我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...

  7. 【Azure 环境】AAD 注册应用获取AAD Group权限接口遇 403 : Attempted to perform an unauthorized operation 错误

    问题描述 通过Azure AD的注册应用获取到Token后,访问AAD Group并查看日志信息时候,遇见了 {"error":{"code":"Un ...

  8. 【Azure 应用服务】使用Python Azure SDK 来获取 App Service的访问限制信息(Access Restrictions)

    问题描述 为Azure App Service添加访问限制,需要Python Azure SDK来实现的示例代码. 问题解答 查阅Azure App Service的官方资料,使用Python SDK ...

  9. 【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App

    问题描述 如图上,是App Services在Windows环境中,系统自带了MySQL In App功能.而在,Linux环境中,没有发现Mysql in App功能,是不是无法在Linux中使用呢 ...

  10. 代码随想录算法训练营第三十天| 51. N皇后 37. 解数独 总结

           卡哥建议:今天这三道题都非常难,那么这么难的题,为啥一天做三道? 因为 一刷 也不求大家能把这么难的问题解决,所以 大家一刷的时候,就了解一下题目的要求,了解一下解题思路,不求能直接写出 ...