zoukankan      html  css  js  c++  java
  • Gym

    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

    题解:

    看起来很简单的题   我还是做了很久 基础知识点有很多漏洞吧

    本题就是一个 C(n,k)+C(n,k+1)+...+C(n,n) 的过程

    如果暴力算的话会超时  哭叽叽

    要知道组合数的总和是2^n

    所以转化成 2^n - C(n,0)+C(n,1)+...+C(n,k-1)

    加减乘可直接用同余定理直接拆开算  除法不行 

    所以利用费马小定理(假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。)

    得到推论  a*a(p-2)≡1(mod p)对于整数a,p,a关于p的逆元就是a^(p-2),直接快速幂解之即可,但注意这个定理要求a,p互质

    利用上述方法求得逆元

    计算乘方时用到快速幂

    如此这一问题便解决了

    (我的第一篇博客,欢迎大家批评指正^-^)

    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    typedef long long ll;
    const int N=1e5+7;
    const ll mod=1e9+7;
    
    ll quick(ll a,ll b)            //快速幂
    {
        ll ans=1;
        a%=mod;
        while(b){
            if(b&1) ans=ans*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return ans;
    }
    
    int main()
    {
        ll n,k,i;
        int l=1,t;
        scanf("%d",&t);
        while(t--){
            scanf("%I64d%I64d",&n,&k);
            ll ans=quick(2,n)-1;      //2^n-C(n,0)
            ll cur=n;
            for(i=1;i<k;i++){
                ans=(ans+mod-cur)%mod;       //emmm  为啥要加个mod我还不太了解,如果有大佬知道,麻烦指点一下
                cur=cur*(n-i)%mod;
                cur=cur*quick(i+1,mod-2)%mod;        //乘以逆元
            }
            printf("Case #%d: %I64d
    ",l++,ans);
        }
        return 0;
    }
  • 相关阅读:
    期末实训学习认识SSH
    Hibernate 的认识
    action和domain的不同总结
    学习使用action属性来接受参数
    实现action的统配
    struts2学习
    路径问题--笔记
    学习C层
    innovus add_ndr rule
    innovus clock tree instance ccl cdb cwb等 名字命名含义
  • 原文地址:https://www.cnblogs.com/y1040511302/p/9600887.html
Copyright © 2011-2022 走看看