由题推出,需要求:
C(n,k) + C(n,k+1) +...+ C(n,n);
由于n巨大(1e9),而k 1e5;
可以转化为: 2^k - ( C(n,0) + C(n,1) + ... + C(n,k-1) )
C(n,k) = ( n*(n-1)*..(n-k+1) ) / ( k! );
恰好O(k)解决
因为涉及到分数取模,所以还要预处理 inv(k!) ,逆元打表见代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1e5 + 1;
const ll MOD = 1e9 + 7;
ll inv[maxn];
void init() {
inv[1] = 1;
for(int i = 2; i < maxn; ++i) {
inv[i] = (MOD-(MOD/i))*inv[MOD%i] % MOD;
}
}
ll quickPower(ll a, ll b) {
ll ans = 1;
while(b) {
if(b&1) {
ans = (ans*a)%MOD;
}
b >>= 1;
a = (a*a) % MOD;
}
return ans;
}
int main() {
// C(n,k) + C(n,k+1) +... + C(n, n);
init();
int T;
scanf("%d", &T);
for(int test = 1; test <= T; ++test) {
ll n, k;
scanf("%lld%lld", &n, &k);
ll ans = quickPower(2,n)-1;
ll t = n, sum = 0;
for(ll i = 1; i < k; ) {
sum = (sum + t) % MOD;
t = (t*(n-i)%MOD*inv[++i]) % MOD;
}
ans = (ans + MOD - sum) % MOD;
printf("Case #%d: %lld\n", test, ans);
}
return 0;
}