1. 程式人生 > >Gym 101775A - Chat Group - [簡單數學題][2017EC-Final]

Gym 101775A - Chat Group - [簡單數學題][2017EC-Final]

spa $2 where example orm ould can c代碼 print

題目鏈接:http://codeforces.com/gym/101775/problem/A

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?≤?10^9.
3?≤?K?≤?10^5.

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

題意:

聽說一個寢室六個人有七個群?但實際上如果六人寢裏三個人及以上組成不同的群的話,可以組成 $42$ 個群……

現在給出一個 $n$ 人寢室,要求計算 $k$ 人及以上的不同的群可以建幾個?

題解:

$C_{n}^{k}+ \cdots + C_{n}^{n} = (C_{n}^{0}+ C_{n}^{1} + \cdots + C_{n}^{n}) - (C_{n}^{0}+ C_{n}^{1} + \cdots + C_{n}^{k-1})$

又根據二項式展開可知 $2^n = (1+1)^{n} = C_{n}^{0} \times 1^{0} \times 1^{n} + C_{n}^{1} \times 1^{1} \times 1^{n-1} + \cdots + C_{n}^{n} \times 1^{n} \times 1^{0} = C_{n}^{0} + C_{n}^{1} + \cdots + C_{n}^{n}$

因此答案即為 $2^{n} - (C_{n}^{0}+ C_{n}^{1} + \cdots + C_{n}^{k-1})$。

運用累乘的方式計算 $C_{n}^{0}, C_{n}^{1}, \cdots, C_{n}^{k-1}$,註意除法要使用逆元。

AC代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=1000000007;
ll n,k;

ll fpow(ll a,ll b)
{
    ll r=1,base=a%MOD;
    while(b)
    {
        if(b&1) r*=base,r%=MOD;
        base*=base;
        base%=MOD;
        b>>=1;
    }
    return r;
}
ll inv(ll a){return fpow(a,MOD-2);}

int main()
{
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++)
    {
        scanf("%lld%lld",&n,&k);
        if(n<k)
        {
            printf("Case #%d: 0\n",kase);
            continue;
        }
        ll sum=1+n,tmp=n;
        for(ll i=1;i<=k-2;i++)
        {
            tmp=(((tmp*(n-i))%MOD)*inv(i+1))%MOD;
            sum=(sum+tmp)%MOD;
        }
        ll ans=(fpow(2,n)-sum+MOD)%MOD;
        printf("Case #%d: %d\n",kase,ans);
    }
}

Gym 101775A - Chat Group - [簡單數學題][2017EC-Final]