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

    有一棵二叉树,初态下没有结点。第一天会长出一个根结点,每个结点都有两个分叉,后面每天都会选择一个还没挂结点的分叉长出一个结点,并标上这天的时间戳。一棵树的权值为它的所有节点两两距离和。经过 (n) 天,有可能会生成 (n!) 棵不同的树,求这些树的权值和。(n leq 2000)

    Solution

    考虑当前已经放置了 (i) 个点

    按边统计,先枚举深子树为 (j) 大小的边,然后统计它出现了多少次,每次对答案贡献为 (2j(n-j))

    (i) 个点无限制,有 (i!) 种造法

    大小为 (j) 的深子树需要从剩下的 (n-i) 个点中选出 (j) 个点造树,有 (C_{n-i}^j j!) 种造法

    剩下的点不能放在上述深子树中,所以第一个点有 (i) 种放法,第二个点有 (i+1) 种放法

    于是答案为

    [sum_{i=1}^n sum_{j=1}^{n-i} 2j(n-j) i! C_{n-i}^j j!frac{(n-j-1)!}{(i-1)!}=sum_{i=1}^nsum_{j=1}^{n-i} 2ij(n-j)C_{n-i}^j j!(n-j-1)! ]

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 2005;
    
    int n,mod,c[N][N],f[N],ans;
    
    signed main() {
        cin>>n>>mod;
        f[0]=1;
        for(int i=1;i<=n;i++) f[i]=f[i-1]*i%mod;
        for(int i=0;i<=n;i++) {
            c[i][0]=1;
            for(int j=1;j<=i;j++) {
                c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
            }
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n-i;j++) {
                ans+=2*i*j%mod*(n-j)%mod*c[n-i][j]%mod
                    *f[j]%mod*f[n-j-1]%mod;
                ans%=mod;
            }
        }
        cout<<ans;
    }
    
    
  • 相关阅读:
    Python中的self详细解析
    promise
    JavaScript 中的let、const、val的区别
    Vuex
    继承
    原型及原型链
    this,call,apply,bind之间的关系
    Js 数据类型
    JS数据类型判断
    H5新特性
  • 原文地址:https://www.cnblogs.com/mollnn/p/12433208.html
Copyright © 2011-2022 走看看