P12992 题解
dAniel_lele · · 题解
从大到小加边,做一个转化,
考虑容斥,选定
首先给这
总复杂度
#include <bits/stdc++.h>
#define int long long
#define lowbit(i) (i&(-i))
using namespace std;
const int mod=1e9+7;
int qp(int a,int b){
a%=mod;
int ans=1;
while(b){
if(b&1) (ans*=a)%=mod;
(a*=a)%=mod;
b>>=1;
}
return ans;
}
int fac[1000005],inv[1000005],invp[1000005],ipw[1000005];
void init(){
ipw[0]=1; for(int i=1;i<=1000000;i++) ipw[i]=ipw[i-1]*((mod+1)>>1)%mod;
fac[0]=1; for(int i=1;i<=1000000;i++) fac[i]=fac[i-1]*i%mod;
inv[1000000]=qp(fac[1000000],mod-2); for(int i=999999;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
for(int i=1;i<=1000000;i++) invp[i]=fac[i-1]*inv[i]%mod;
}
int C(int i,int j){
if(i<0||j<0||i<j) return 0;
return fac[i]*inv[j]%mod*inv[i-j]%mod;
}
int f[1000005];
void solve(int tc){
int n,k; cin>>n>>k;
f[0]=1;
for(int i=1;(i<<1)<=n;i++) f[i]=f[i-1]*qp((i<<1)*(n-(i<<1))+i*((i<<1)-1),mod-2)%mod;
int ans=0;
for(int i=k;(i<<1)<=n;i++){
if((i-k)&1) (ans+=mod-f[i]*C(i,k)%mod*fac[n]%mod*ipw[i]%mod*inv[n-(i<<1)]%mod)%=mod;
else (ans+=f[i]*C(i,k)%mod*fac[n]%mod*ipw[i]%mod*inv[n-(i<<1)]%mod)%=mod;
}
cout<<"Case #"<<tc<<": "<<ans<<"\n";
}
signed main(){
init();
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t; cin>>t;
for(int i=1;i<=t;i++) solve(i);
return 0;
}