正题
题目链接:https://ac.nowcoder.com/acm/contest/11161/C
题目大意
nnn个点加mmm条边使得不存在环,每种方案的权值是所有联通块的大小乘积。
求所有方案的权值和。
1≤n≤109,1≤m≤1071\leq n\leq 10^9,1\leq m\leq 10^71≤n≤109,1≤m≤107
解题思路
就是分成n−mn-mn−m个树,然后权值比较麻烦。
但是发现权值是大小,所以可以理解为有根树,这样就是纯粹的求方案数了。
然后我们还可以优化,设虚根000,我们限制其度数为n−mn-mn−m就可以分为n−mn-mn−m个有根树了。
所以用PruferPruferPrufer序列统计的话方案数就是
(n−1m)×nm\binom{n-1}{m}\times n^m(mn−1)×nm
时间复杂度O(n)O(n)O(n)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll P=1e9+7;
ll n,m,C,inv[11000000];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
signed main()
{scanf("%lld%lld",&n,&m);ll C=1;for(ll i=1;i<=m;i++)C=C*(n-i)%P;inv[1]=1;for(ll i=2;i<=m;i++)inv[i]=P-inv[P%i]*(P/i)%P,C=C*inv[i]%P;printf("%lld\n",C*power(n,m)%P);
}