版权声明:喜欢请点个大拇指,感谢各位dalao。弱弱说下,转载要出处呦 https://blog.csdn.net/qq_35786326/article/details/82946525
题目:
分析:
我们以
的两种情况进行分析:
当
时:果断输出
当
时:我们可以用
条边,将这
个点组成的图划分为
个部分,那么这样的话我们就考虑将这
个部分进行排列,也就是
的全排列
而我们一共有
条边,要选出
条,即求组合:
当然这样还是只能得到部分分,因为
实在太大了,需要边运算边模,但除法并不具有这样的性质,故我们要将其转化为乘法,我们知道除以一个数,等于乘以这个数的乘法逆元,而再根据费马小定理可以知道一个数
的乘法逆元
而对于上述式子,可以通过快速幂迅速求解
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
const int h=1 << 20;
#define ch cheap
#define XJQ (int)1000000007
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
LL n,m;
LL f[(int)1e5+5];
void fac()
{
f[1]=1;
for(int i=2;i<=n;i++) f[i]=(LL)f[i-1]*i%XJQ;
return;
}
LL gd(LL x,LL y)
{
LL ans=1;
while(y)
{
if(y&1) ans=ans*x%XJQ;
y/=2;
x=x*x%XJQ;
}
return ans;
}
LL c()
{
return f[n-1]*gd(f[m-1]*f[n-m]%XJQ,XJQ-2)%XJQ;
}
int main()
{
LL t=read();
LL x;
while(t--)
{
n=read(),m=read();
fac();
for(int i=0;i<2*n-2;i++) x=read();
if(m==1) {printf("1\n");continue;}
printf("%lld\n",(c())*f[m]%XJQ);
}
return 0;
}