zoukankan      html  css  js  c++  java
  • 51nod1805 小树

    题意:输入N,M,(2<=n, m<=1000000)一颗有标号无根树n个节点,有m个叶子节点,问有多少颗满足条件的树

    题解:一颗有标号的无根树可以一一对应一个prufer序列,有一个定理:prufer序列中出现数字的次数+1是这个数字标号的度数,那么这里可以知道度数为1的有m个,也就是问恰好有1-n中的n-m种数且长度为n-2的序列有多少个,容斥+组合数

    #include <bits/stdc++.h>
    #define ll long long
    #define maxn 1000100
    using namespace std;
    const ll mod = 1e9+7;
    ll fc[maxn], fi[maxn];
    ll f(ll a,ll b){
        ll ans = 1;
        while(b){
            if(b&1) ans = ans*a%mod;
            a = a*a%mod;
            b >>= 1;
        }
        return ans;
    }
    void init(){
        fc[0] = 1;
        for(ll i=1;i<maxn;i++) fc[i] = fc[i-1]*i%mod;
        fi[maxn-1] = f(fc[maxn-1], mod-2);
        for(ll i=maxn-1;i>=1;i--) fi[i-1] = fi[i]*i%mod;
    }
    ll c(ll n,ll m){
        return fc[n]*fi[m]%mod*fi[n-m]%mod;
    }
    int main(){
        init();
        ll n, m, ans = 0;
        scanf("%lld%lld", &n, &m);
        if(n == 2) return 0*printf("1
    ");
        for(ll i=n-m;i>=1;i--){
            if((n-m-i)&1) ans -= c(n-m, i)*f(i, n-2)%mod;
            else ans += c(n-m, i)*f(i, n-2)%mod;
            ans = (ans+mod)%mod;
        }
        printf("%lld
    ", ans*c(n, n-m)%mod);
        return 0;
    }
  • 相关阅读:
    图解C/C++多级指针与多维数组
    排序---选择排序
    排序---插入排序
    排序---希尔排序
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    如何阅读Django文档?
    机器学习 第一章 绪论 笔记
    python工程实践·笔记
    Python后端开发面经
  • 原文地址:https://www.cnblogs.com/Noevon/p/8405100.html
Copyright © 2011-2022 走看看