• Chat Group gym101775A(逆元,组合数)


    传送门:Chat Group(gym101775A)

    题意:一个宿舍中又n个人,最少k(k >= 3)个人就可以建一个讨论组,问最多可以建多少个不同的讨论组。

    思路:求组合数的和,因为涉及除法取余,所以要求逆元来解题。

    虽然之前看到过有关逆元的知识,但是一直没有弄明白逆元的应用。嗯~~挖下的坑终于把自己给坑了。这次认栽!!

    最终的结果是:C(n,k)+C(n,k+1)+.......+C(n,n) = 2^n - ( C(n,0) + C(n,1) + C(n,2) + ......+C(n,k-1)

    (a / b)%mod = a % mod *(b关于模mod的逆元);

    复习逆元相关知识:Click hear

    代码: 

    费马小定理求逆元法:

    #include <bits/stdc++.h>
    using namespace std;
    const int MOD = 1e9+7;
    const int maxn = 1e5;
    typedef long long ll;
    int n,k;
    ll qpow(ll a,ll b)
    {
        ll res = 1;
        while(b)
        {
            if(b&1)
                res = res*a%MOD;
            a = a*a%MOD;
            b>>=1;
        }
        return res;
    }
    
    
    int main()
    {
        int T,cnt = 0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&k);
            ll c = 1;
            ll sum = 0;
            for(int i = 1; i<=k-1; i++)
            {
                c = ((c*(n-i+1)%MOD)*qpow(i,MOD-2))%MOD;
                sum = (sum + c)%MOD;
            }
            ll M = qpow(2,n) - 1;
            printf("Case #%d: %lld
    ",++cnt,(M - sum + MOD)%MOD);//将结果转为正数
        }
        return 0;
    }
    View Code

    线性求逆元:

    #include <bits/stdc++.h>
    using namespace std;
    const int MOD = 1e9+7;
    const int maxn = 1e5;
    typedef long long ll;
    int n,k;
    ll qpow(ll a,ll b)
    {
        ll res = 1;
        while(b)
        {
            if(b&1)
                res = res*a%MOD;
            a = a*a%MOD;
            b>>=1;
        }
        return res;
    }
    ll inv[maxn];
    
    void getInv()
    {
        inv[1] = 1;
        for(int i = 2; i<maxn; i++)
        {
            inv[i] = (MOD-MOD/i)*inv[MOD%i]%MOD;
        }
    }
    
    int main()
    {
        int T,cnt = 0;
        scanf("%d",&T);
        while(T--)
        {
            getInv();
            scanf("%d%d",&n,&k);
            ll c = 1;
            ll sum = 0;
            for(int i = 1; i<=k-1; i++)
            {
                c = (c*(n-i+1)%MOD*inv[i])%MOD;
                sum = (sum + c)%MOD;
            }
            ll M = qpow(2,n) - 1;
            printf("Case #%d: %lld
    ",++cnt,(M - sum + MOD)%MOD);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    统计 (Standard IO)
    存储过程中的错误处理
    簡單SQL存儲過程實例
    SQLSERVER存储过程基本语法
    SQL Server游标的使用【转】
    实现业务系统中的用户权限管理--实现篇
    实现业务系统中的用户权限管理--设计篇
    C#.net 微信公众账号接口开发
    jquery select radio
    asp.net Repeater使用例子,包括分页
  • 原文地址:https://www.cnblogs.com/sykline/p/9737764.html
Copyright © 2020-2023  润新知