P7392 题解
_saltFish_ · · 题解
题意很明显,该伪代码就是归并排序的版子,只不过是规定了层数为
我们知道对于一个有
因为归并排序是从中间划分并递归,所以在第
只要将全排列数
而对于分数的乘法相当于除法,在需要取摸的情况下要求逆元。
特殊的,对于
但由于
当
#include<iostream>
#define ll long long
const int mod(1e9+7);
using namespace std;
ll t,n,k,jc[1000005]={0,1};
ll qpow(ll a,ll b){
ll s=1;
while(b){
if(b&1) s=s*a%mod;
a=a*a%mod;
b>>=1;
}
return s;
}
int main(){
#ifdef ytxy
freopen("in.txt","r",stdin);
#endif
cin>>t;
for(int i=2;i<=1e6;i++) jc[i]=jc[i-1]*i%mod;
while(t--){
cin>>n>>k;
if(k>20||(1<<k)>=n)
cout<<jc[n]<<'\n';
else if(k==0)
cout<<1<<'\n';
else
cout<<1ll*qpow(qpow(jc[n/(1<<k)],mod-2)/*逆元*/,1<<k)
*qpow(qpow(n/(1<<k)+1,mod-2),n%(1<<k))%mod/*此前为求概率(所有第k层子集有序的总概率)*/
*jc[n]/*全排列数*/%mod<<'\n';
}
}