const int maxn=4e5+7;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll fac[maxn];///阶乘
ll inv[maxn];///阶乘逆元
ll quick_pow(ll a,ll b,ll p)
{
ll ans=1;
while (b)
{
if (b&1)///b为奇数
ans=(ans*a)%p;
a=(a*a)%p;///b为偶数
b>>=1;
}
return ans;
}
void init()
{
fac[0] = 1;
for (int i = 1; i < maxn; i++)
{
fac[i] = fac[i - 1] * i % mod;
}
inv[maxn - 1] = quick_pow(fac[maxn - 1],mod - 2,mod);
for (int i = maxn - 2; i >= 0; --i)
{
inv[i] = inv[i + 1] * (i + 1) % mod;
}
}
int prime[maxn+2];//prime[0]记录当前为止找到的素数的个数,1~n存找到的素数
int visit[maxn+2];//0表示是素数
void Prime()
{
memset(visit,0,sizeof(visit));
memset(prime, 0,sizeof(prime));
for (int i = 2; i <= maxn; i++)
{
if (visit[i]==0)
{
prime[++prime[0]] = i;//记录素数的个数,同时存找到的素数
}
for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++)//遍历每一个已找到的素数
{
visit[i*prime[j]] = prime[j];//这个素数的倍数是合数
if (i % prime[j] == 0)//因为每个数只被它的最小质因子筛一次,在此之后的质数不用筛,以后会筛
{
break;
}
}
}
}
ll c(ll n,ll m)///Cnm
{
if (m>n||n<0||m<0)return 0;
if(n < maxn) return (fac[n] * inv[m] % mod * inv[n - m] % mod)%mod;
//c(n,m) = n!/m!*(n-m)!
}