【组合数】微信群 @upcexam6016

时间限制: 1 Sec 内存限制: 128 MB
题目描述
众所周知,一个有着6个人的宿舍可以有7个微信群(^_^,别问我我也不知道为什么),然而事实上这个数字可以更大,因为每3个或者是更多的人都可以组建一个群,所以6个人最多可以组建42个不同的群。
现在,已知一间宿舍有N个人,并且每至少K个人都可以组建一个微信群,那么他们最多可以组建多少个不同的微信群?
输入
一行两个整数N和K,表示宿舍中的人数和最少能够组建微信群的人数
输出
一行一个整数,即最多能组建多少个不同的微信群,由于这个数字很大,请输出对10^9+7求余后的结果
样例输入
6 3
样例输出
42
提示
对于30%的数据,3<=N<=10^3
对于60%的数据,3<=N<=10^6
对于100%的数据,3<=N<=10^9,3<=K<=10^5

题目要求ans = ni=kCin

根据组合数的性质 ni=0Cin = 2n

所以ans = 2n - k1i=0Cin

而由Cmn = Cm1nnm+1m

可以O(N)线性求出ans

#define FILE() freopen("../../in.txt","r",stdin)
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxk = 100005;
const ll MOD = 1e9+7;

ll fastpower(ll x,ll n) {
    ll res = 1;
    while(n) {
        if(n&1)res = res*x%MOD;
        x = x*x%MOD;
        n>>=1;
    }
    return res;
}

int main() {
    //FILE();
    ll k,n;
    cin>>n>>k;
    ll sum = fastpower(2,n),ans=1,tmp=n;
    for(int i=2; i<=k; i++) {
        ans=(ans+tmp)%MOD;
        tmp=((tmp*(n-i+1))%MOD*fastpower(i,MOD-2))%MOD;
    }
    ans=(sum-ans+MOD)%MOD;
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/NeilThang/p/9356626.html