题意
询问有多少个NNN个点,MMM条边的有向图,从111号点到达NNN号点需要经过至少N−1N-1N−1条边。该有向图中可以包含重边和自环。方案数%1000000009\%1000000009%1000000009。
思路
因为至少是N−1N-1N−1条边,所以这构成了一条链,我们要在这链里加边且不是捷径边。
一共可以加入N2N^2N2条边,捷径边的边数有CN−12C_{N-1}^{2}CN−12条边,那么还能加进去的边还有N2−CN−12N^2-C_{N-1}^{2}N2−CN−12。
因为图中有MMM条边,用了N−1N-1N−1条边,所以还剩M−N+1M-N+1M−N+1条边,我们要把这能加进的N2−CN−12N^2-C_{N-1}^{2}N2−CN−12边放到这里面。
这里给出一个公式,把NNN个相同的元素放进MMM个桶的方案数为CN+M−1NC_{N+M-1}^{N}CN+M−1N
然后我们就可以套公式求出答案了,然后取模就直接算逆元。
代码
#include<cstdio>
const int P = 1e9 + 7;
int n, m;
int fact[10001];
int power(int a, int b) {
int result = 1;
a %= P;
for (; b; b >>= 1) {
if (b & 1) result = (long long)result * a % P;
a = (long long)a * a % P;
}
return result;
}
long long C(int n, int m) {
long long a = 1, b = 1;
for (int i = n; i > n - m; i--)
a = a * i % P;
for (int i = 1; i <= m; i++)
b = b * power(i, P - 2) % P;
return a * b % P;
}
int main() {
scanf("%d %d", &n, &m);
fact[0] = 1;
for (int i = 1; i <= n - 2; i++)
fact[i] = (long long)fact[i - 1] * i % P;
printf("%d", C(n * n - C(n - 1, 2) - 1 + m - n + 1, m - n + 1) * fact[n - 2] % P);
}