zoukankan      html  css  js  c++  java
  • [HAOI2018]苹果树

    首先发现一次生长相当于去掉一个分支并增加两个分支, 那么所有树出现的概率都是相同的, 一共有 N! 种树。

    所以要求输出的那个东西就是不便度的平均数 * 树的总数, 即所有树的不便度之和。

    对于某棵树的不便度, 把它拆到边上, 具体地, 这棵树的不便度等于 (sum_u siz(u) * (n - siz(u)))

    设 cntu,s 表示点 u 的 siz 为 s 的方案数。(1≤s≤n-u+1)

    首先, 生成 1~u, (color{red}{u!})

    其次, 决定 u 子树中的点的标号,(color{red}{dbinom {n-u}{s-1}}), 然后生成以 u 为根的子树, (color{red}{s!})

    然后生成整棵树的其余部分,(color{red}{(u-1)(u-1+1)cdots(u-1+(n-u-s+1)-1)} = dfrac{(n-s-1)!}{(u-2)!})

    所以答案就是:

    [sum_{u=1}^nsum_{s=1}^{n-u+1} s(n-s)u!inom{n-u}{s-1}s!frac{(n-s-1)!}{(u-2)!} ]

    这道题的模数不保证是质数, 组合数可以预处理,只需要化掉除法:

    [egin{align} &s(n-s)u!inom{n-u}{s-1}s!frac{(n-s-1)!}{(u-2)!}\ &= sinom{n-u}{s-1}s!(n-s)!(u-1)u end{align} ]

    #include<bits/stdc++.h>
    typedef long long LL;
    using namespace std;
    
    const int N = 2e3 + 3;
    
    int n, mo;
    LL C[N][N], fac[N];
    
    int main() {
    	scanf("%d%d", &n, &mo);
    	fac[0] = 1ll, C[0][0] = 1ll;
    	for(int i = 1; i <= n; ++i) fac[i] = fac[i-1] * (LL)i % mo;
    	for(int i = 1; i <= n; ++i) {
    		C[i][0] = 1ll;
    		for(int j = 1; j <= n; ++j) C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mo;
    	}
    	LL ans = 0ll;
    	for(int u = 1; u <= n; ++u) {
    		for(int s = 1; s <= n-u+1; ++s) {
    			ans += (LL)s * C[n-u][s-1] % mo * fac[s] % mo * fac[n-s] % mo * (LL)u % mo * (LL)(u-1) % mo;
    			ans %= mo;
    		}
    	}
    	cout << (ans%mo + mo) % mo;
    	return 0;
    }
    
  • 相关阅读:
    SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
    麦咖啡导致电脑不能上网
    SharePoint 2013 Central Admin 不能打开
    SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
    SharePoint 2013 APP 开发示例 系列
    synthesize(合成) keyword in IOS
    Git Cmd
    简单的正则匹配
    Dropbox
    SQL Server Replication
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14351884.html
Copyright © 2011-2022 走看看