EC-final2017 A - Chat Group Gym - 101775A(组合数)

It is said that a dormitory with 6 persons has 7 chat groups _. But the number can be even larger: since every 3 or more persons could make a chat group, there can be 42 different chat groups.

Given N persons in a dormitory, and every K or more persons could make a chat group, how many different chat groups could there be?

Input
The input starts with one line containing exactly one integer T which is the number of test cases.

Each test case contains one line with two integers N and K indicating the number of persons in a dormitory and the minimum number of persons that could make a chat group.

1 ≤ T ≤ 100.
1 ≤ N ≤ 109.
3 ≤ K ≤ 105.
Output
For each test case, output one line containing “Case #x: y” where x is the test case number (starting from 1) and y is the number of different chat groups modulo 1000000007.

Example
Input
1
6 3
Output
Case #1: 42

题意:
求出n个人,选出至少m个人的方案数。
思路:
就是∑C(i,n) m ≤ i ≤ n。
转变成2n - ∑C(j,n) 0 ≤ j ≤ n。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 2e5 + 7;
const int mod = 1000000007;
typedef long long ll;
ll fac[maxn],inv[maxn];
ll fac_rev[maxn];
ll qpow(ll a,ll b)
{
    ll res = 1;
    while(b)
    {
        if(b & 1)
        {
            res = (res * a) % mod;
        }
        a = (a * a) % mod;
        b = b >> 1;
    }
    return res % mod;
}

ll C(ll n,ll m)
{
    if(m > n || m < 0)
        return 0;
    // return fac[n] * ((inv[n - m] * inv[m]) % mod) % mod;
    return fac_rev[n] * inv[m] % mod;
}

void init()
{
    fac[0] = 1;
    inv[0] = 1;
    for(int i = 1;i <= maxn - 2;i++)
    {
        fac[i] = (fac[i - 1] * i) % mod;
        inv[i] = qpow(fac[i],mod - 2);
    }
    
    
}

void init2(ll n,ll k)
{
	fac_rev[1] = n;
	for(ll i = 2;i <= k - 1;i++)
    {
    	fac_rev[i] = fac_rev[i - 1] * (n - i + 1) % mod;
    }
}

int main()
{
	int T;scanf("%d",&T);
	init();
	int kase = 0;
	while(T--)
	{
		ll n,k;scanf("%lld%lld",&n,&k);
		ll ans = qpow(2,n);
		init2(n,k);

		for(ll i = 1;i <= k - 1;i++)
		{
			ans = ((ans - C(i,i)) % mod + mod) % mod;
		}
		ans--;
		if(ans < 0)ans += mod;
		printf("Case #%d: ",++kase);
		printf("%lld\n",ans % mod);
	}
	return 0;
}
发布了594 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/103514649