Summary

题意很清楚:

小 \(C\) 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支.

经过细心的观察, 小 \(C\) 发现每一天这棵树都会生长出一个新的结点.

第一天的时候, 果树会长出一个根结点, 以后每一天, 果树会随机选择一个当前树中没有长出过结点的分支, 然后在这个分支上长出一个新结点, 新结点与分支所属的结点之间连接上一条边.

小 \(C\) 定义一棵果树的不便度为树上两两结点之间的距离之和, 两个结点之间 的距离定义为从一个点走到另一个点的路径经过的边数.

现在他非常好奇, 如果 \(N\) 天之后小 \(G\) 来他家摘苹果, 这个不便度的期望 \(E\) 是多少. 但是小 \(C\) 讨厌分数, 所以他只想知道 \(E \times N!\) 对 \(P\) 取模的结果, 可以证明这是一个整数.

Solution

一开始想用树形DP,但是发现子树间不是独立的,所以用不了。

首先可以发现,每次加上一个点以后,其父节点少了一个空位,但是他自己有提供了两个空位。

因此每增加一个节点,都会多一个空位。添加第$i$个点的时候,就有$i$个空位。

所以总方案数为$N!$。因此,$E\times N!$就是所有形态的树的的不便度总和。

根据这种题目的套路,应该考虑每条边的贡献。但是发现所有的边都是不确定的。

但是好好想想,其实只要一个点的子树大小确定了,其连向父节点的边的贡献也就定下来了。每一个子树内的点和子树外的点的搭配,都会经过这条边。因此,假设子树大小为$j$,那么那个点连向其父节点的边的贡献就是$j\cdot(n-j)$。

然后考虑每一个子树的根节点,设其为$i$。因为加点是有顺序的,我们不妨假设编号为$i$的点是第$i$个加入的。

那么这$i$个点的形态就有$i!$种。然后子树内,也有$j!$种形态。

但是子树内有哪些点呢?

首先这些点的组合肯定是$C_^$种。因为加点顺序是定下来的,所以不需要考虑加点顺序带来的不同的树。

然后只剩下了子树外的。

子树外呢,前$i-1$个点加完以后,有$i$个空位。有一个空位被$i$占掉了,那么还剩下$i-1$个空位。

因为除了$i$这棵子树,以及已经加过的点,还剩下$n-i-j+1$个点。

每次加一个点,多一个空位。所以每一多一个空位,直到加完,那么最后一次加点前的空位数为$i-1+n-i-j+1-1=n-j-1$,注意最后一次$-1$是因为最后一次还没有加点。

所以那些点的形态有$\prod \limits_^ k$个。

那么总共,第$i$个点的子树大小为$j$的贡献就是

\[
j\cdot(n-j)\cdot j! i!\cdot C_{n-i}^{j-1}\cdot \prod_{k=i-1}^{n-j-1}k
\]

这个东西再化一化,后面的连乘和前面的$i!,\ (n-j)$可以合并到一起,然候再拎出中间重复的。

\[
ij(i-1)\cdot j!\cdot (n-j)!\cdot C_{n-i}^{j-1}
\]

然候就可以$O(n^2)$ 枚举$i,\ j$,计算出来了。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define REP(i,a,n) for(register int i=a;i<=n;++i)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
typedef long long ll;
const int N=2000+7;
int n,P,C[N][N],fac[N],ans;
inline void SADD(int&x,const int&y){x+=y;x>=P?x-=P:0;}//´íÎó±Ê¼Ç£º-=µÈºÅÍü´òÁË
inline int SMOD(int x){return x>=P?x-P:x;}
inline void Preprocess(){
C[0][0]=fac[0]=1;
REP(i,1,n){
C[i][0]=1;fac[i]=(ll)fac[i-1]*i%P;
REP(j,1,i)C[i][j]=SMOD(C[i-1][j-1]+C[i-1][j]);
}
}
int main(){
scanf("%d%d",&n,&P);
Preprocess();
REP(i,2,n)REP(j,1,n-i+1)SADD(ans,(ll)j*i*(i-1)%P*fac[j]%P*fac[n-j]%P*C[n-i][j-1]%P);
printf("%d\n",ans);
}

[BZOJ5305] [HAOI2018] 苹果树 数学 组合计数的更多相关文章

  1. 【BZOJ5305】[HAOI2018]苹果树(组合计数)

    [BZOJ5305][HAOI2018]苹果树(组合计数) 题面 BZOJ 洛谷 题解 考虑对于每条边计算贡献.每条边的贡献是\(size*(n-size)\). 对于某个点\(u\),如果它有一棵大 ...

  2. [BZOJ5305][HAOI2018]苹果树(DP)

    首先注意到每种树都是等概率出现的,于是将问题转化成计数求和问题. f[n]表示所有n个点的树的两两点距离和的总和. g[n]表示所有n个点的树的所有点到根的距离和的总和. h[n]表示n个点的树的可能 ...

  3. BZOJ5305 HAOI2018苹果树(概率期望+动态规划)

    每种父亲编号小于儿子编号的有标号二叉树的出现概率是相同的,问题相当于求所有n个点的此种树的所有结点两两距离之和. 设f[n]为答案,g[n]为所有此种树所有结点的深度之和,h[n]为此种树的个数. 枚 ...

  4. BZOJ5305 [Haoi2018]苹果树 【组合数学】

    题目链接 BZOJ5305 题解 妙啊 要求的是所有可能的树形的所有点对距离和 直接考虑点的贡献肯定想不出,这样的所有点对距离问题通常转化为边的贡献 考虑一条边会产生多少贡献 我们枚举\(i\)节点的 ...

  5. [BZOJ5305][Haoi2018]苹果树 组合数

    题目描述 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C 发现每一天这棵树都会生长出一个新的结点. 第一天的时候, 果树会长出一个根结点, 以后每一 ...

  6. [BZOJ5305][HAOI2018]苹果树 组合数学

    链接 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C 发现每一天这棵树都会生长出一个新的结点. 第一天的时候, 果树会长出一个根结点, 以后每一天, ...

  7. BZOJ5305: [HAOI2018]苹果树

    传送门 果然只有我这种菜鸡才会用这种菜鸡做法QwQ 对于一类要求期望的题目,有一个无脑的做法: 设概率为 \(f\),期望为 \(g\) 每次合并两个二元组 \(<f_1,g_1>,< ...

  8. [总结]数论和组合计数类数学相关(定理&证明&板子)

    0 写在前面 0.0 前言 由于我太菜了,导致一些东西一学就忘,特开此文来记录下最让我头痛的数学相关问题. 一些引用的文字都注释了原文链接,若侵犯了您的权益,敬请告知:若文章中出现错误,也烦请告知. ...

  9. [HAOI2018]苹果树(组合数学,计数)

    [HAOI2018]苹果树 cx巨巨给我的大火题. 感觉这题和上次考试gcz讲的那道有标号树的形态(不记顺序)计数问题很类似. 考虑如果对每个点对它算有贡献的其他点很麻烦,不知怎么下手.这个时候就想到 ...

随机推荐

  1. 2017 ICPC HongKong B:Black and White(扫描线+线段树)

    题目描述 Consider a square map with N × N cells. We indicate the coordinate of a cell by (i, j), where 1 ...

  2. maven构建docker镜像异常

    由于没有配置ip+2375端口,导致每次跑的时候,都是连接本地的,一直会报错 [ERROR] Failed to execute goal com.spotify:docker-maven-plugi ...

  3. 20180708-Java运算符

    public class Test{ public static void main(String args[]){ int a = 10; int b = 20; int c = 25; int d ...

  4. js常见的几种设计模式

    一.单例模式 单例模式也称作为单子模式,更多的也叫做单体模式.为软件设计中较为简单但是最为常用的一种设计模式. 在JavaScript里,实现单例的方式有很多种,其中最简单的一个方式是使用对象字面量的 ...

  5. Python分布式爬虫打造搜索引擎完整版-基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站

    Python分布式爬虫打造搜索引擎 基于Scrapy.Redis.elasticsearch和django打造一个完整的搜索引擎网站 https://github.com/mtianyan/Artic ...

  6. activity_main.xml 添加自己画的view 组件

    <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=" ...

  7. Vagrant 官网文档翻译汇总

    入门 Vagrant 入门 - 项目设置 Vagrant 入门 - box Vagrant 入门 - 启动 vagrant 及 通过 ssh 登录虚拟机 Vagrant 入门 - 同步目录(synce ...

  8. 2019/10/27 TZOJ

    1001 Gaussian Prime http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=379 ...

  9. 网络流强化-HDU 3338-上下界限制最大流

    题意是: 一种特殊的数独游戏,白色的方格给我们填1-9的数,有些带数字的黑色方格,右上角的数字代表从他开始往右一直到边界或者另外一个黑格子,中间经过的白格子的数字之和要等于这个数字:左下角的也是一样的 ...

  10. C#将字符串Split()成数组

    string str="aaajbbbjccc";string[] sArray=str.Split('j');foreach(string i in sArray) Respon ...