• [洛谷P4492] HAOI2018 苹果树


    问题描述

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

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

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

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

    输入格式

    从标准输入中读入数据. 一行两个整数 (N, P) .

    输出格式

    输出到标准输出中. 输出一个整数表示答案.

    样例输入

    3 610745795

    样例输出

    24

    数据范围

    (N le 2000,Ple 10^9+7)

    解析

    老套路题了。

    不难发现,第 N 天的树上一定有 N+1 个分支可以长结点。因此,大小为 N 的满足要求的树有 N! 中方法。

    直接统计十分复杂,我们考虑计算每条边的贡献。设当前枚举的是节点 (i) 的父边,其子树大小为 (j) 。那么,在确定树的形态的情况下,这条边会被经过 (j(n-j)) 次。

    接下来分别考虑子树和子树外的形态。对于子树,由之前的结论,有 (j!) 种不同的形态。而考虑编号的问题,子树内的编号一定都大于 (i) 。所以总方案数为 (j!C_{n-i}^{j-1}) 。对于子树外,首先在前 (i) 天时就有 (i!) 中形态。在第 (i) 天之后,除了钦定的在子树内的点以外,其余的每一个点都可以放在子树外的一个分支上,依次有 (i+1-2...n-j-1) 种方案(因为点放在子树内导致的分支增加对子树外没有影响,毕竟不能放上去)。综上,总贡献为

    [j(n-j) imes j!C_{n-i}^{j-1} imes i(i-1)(n-j-1)! ]

    枚举 (i)(j) 即可。

    代码

    #include <iostream>
    #include <cstdio>
    #define int long long
    #define N 2002
    using namespace std;
    int n,mod,i,j,c[N][N],fac[N],ans;
    signed main()
    {
    	scanf("%lld%lld",&n,&mod);
    	for(i=fac[0]=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
    	c[0][0]=1;
    	for(i=1;i<=n;i++){
    		c[i][0]=1;
    		for(j=1;j<=i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    	}
    	for(i=1;i<=n;i++){
    		for(j=1;j<=n-i+1;j++){
    			int tmp=fac[j]*c[n-i][j-1]%mod*i%mod*(i-1)%mod*fac[n-j-1]%mod*j%mod*(n-j)%mod;
    			ans=(ans+tmp)%mod;
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    dp(传球)
    最长上升子序列
    FromData获取表单数据
    php解决高并发问题
    php抽象类、接口、traint详解
    mysql、mongodb、redis 数据库之间的区别
    phpstorm2018 安装及破解方法
    phpstudy添加redis扩展
    mysql触发器trigger 实例详解
    mysql查询系列常考问题
  • 原文地址:https://www.cnblogs.com/LSlzf/p/13388113.html
Copyright © 2020-2023  润新知