#高精度,排列组合、dp#JZOJ 2755 树的计数
题目
求\(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 树的计数的更多相关文章
- [Bzoj3193][JLOI2013]地形生成 (排列组合 + DP)
		3193: [JLOI2013]地形生成 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 459 Solved: 223[Submit][Status ... 
- nyoj1076-方案数量                【排列组合 dp】
		http://acm.nyist.net/JudgeOnline/problem.php?pid=1076 方案数量 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 ... 
- 【noi 2.6_9288】&【hdu 1133】Buy the Ticket(DP / 排列组合 Catalan+高精度除法)
		题意:有m个人有一张50元的纸币,n个人有一张100元的纸币.他们要在一个原始存金为0元的售票处买一张50元的票,问一共有几种方案数. 解法:(学习了他人的推导后~) 1.Catalan数的应用7的变 ... 
- ACdream 1412 DP+排列组合
		2-3 Trees Problem Description 2-3 tree is an elegant data structure invented by John Hopcroft. It is ... 
- LightOJ1005 Rooks(DP/排列组合)
		题目是在n*n的棋盘上放k个车使其不互相攻击的方案数. 首先可以明确的是n*n最多只能合法地放n个车,即每一行都指派一个列去放车. dp[i][j]表示棋盘前i行总共放了j个车的方案数 dp[0][0 ... 
- 【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是素数 ... 
- 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值
		[题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ... 
- HDU 5816 状压DP&排列组合
		---恢复内容开始--- Hearthstone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java ... 
- 2017ACM暑期多校联合训练 - Team 8 1011    HDU 6143    Killer Names      (容斥+排列组合,dp+整数快速幂)
		题目链接 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ... 
- bzoj 3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛——前缀和优化dp / 排列组合
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 好简单呀.而且是自己想出来的. dp[ i ]表示最后一个牡牛在 i 的方案数. 当前 ... 
随机推荐
- 图片Base64编码解码的优缺点及应用场景分析
			随着互联网的迅猛发展,图片在网页和移动应用中的使用越来越广泛.而图片的传输和加载往往是网页性能的瓶颈之一.为了解决这一问题,图片Base64编码与解码技术应运而生.本文将介绍图片Base64相互转换的 ... 
- 案例分享:Qt国产麒麟系统某防“某显示控制项目”(多类设备自动化流程控制,数据分析整合与展示,定位图,深度图,热力图等,多应用协调管控,健壮容错)
			喜报 我司承担的某防"某显示控制项目",已于近日顺利通过湖底验收. 需求 功能简介: 1.多类设备的显示.控制与管理 2.数据的分析与展示,定位图.深度图.热力图等 ... 
- [Linux] Linux 自动挂载mount --bind 实现类似目录硬链的效果 (包含ZFS方案)
			说明 这个命令用以将一个目录挂载到另一个目录,以实现类似于硬链的操作 但是这个命令只是在内存中建立了一个映射,重启系统之后挂载就消失了 而linux是不支持目录硬链的,具体原因见linux为什么不能硬 ... 
- 探索Terraform实践:优化基础设施管理
			Terraform 是管理基础设施及代码(IaC)最常用的工具之一,它能使我们安全且可预测地对基础设施应用更改. Terraform作为一个强大的基础设施即代码工具,为开发人员和运维团队提供了一种简单 ... 
- Tomcat8.5简介
			1. Tomcat简介[1] Apache Tomcat是Servlet/JSP的容器.Tomcat8.5 实现了由 JCP 组织 (Java Community Process) 制定的Servle ... 
- Codeforces Round 926 (Div. 2)(A~D)
			目录 A B C D A 输出最大值减最小值,或者排序算一下答案 #include <bits/stdc++.h> #define int long long #define rep(i, ... 
- CPNtools协议建模安全分析---实例(二)
			首先,token值是变迁的内部的,当变迁点火触发的时候token才会在网络中移动.在颜色Petri网中token是有区分的. 1.我么现在举一个学生吃饼的例子 ,颜色这样定义. s表示一个学生类 ... 
- 完整塔建一个spring 注解版 mybaties 过程可供复制代码
			第一步引导包.新建工程maven模块 pom.xml 中导入相对应包 ++++++++++++++++++++++++++++++++++++++++++++ 1 +++++++ ... 
- ACER 宏碁 笔记本无法进入 grub 引导 + 安全启动失败(security boot fail ) 解决办法
			主要介绍让BIOS首先引导grub的方法 加一点:添加完新的启动选项以后,如果看不到添加的启动项,就先保存重启,再进 BIOS 就可以看到了 我是宏碁的笔记本,装了双系统.之前无意间进了一次 BIOS ... 
- 五大基础dp
			动规条件 • 最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构, 即满足最优化原理. • 无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响.也就是说,某状 ... 
