zoj3557 大组合数取模

来源:互联网 发布:gentoo linux pdf 编辑:程序博客网 时间:2024/05/16 03:33

传送门

题意:从n个数中取m个不相邻的数的取法

思路:取不相邻的数,这不就是传统的插空法吗,不是插板法,不是插板法,不是插板法!先从n中任意选择m个数,然后在剩下的n-m个数中插空来保证不相邻,而插板法一般是相同元素分组,不相邻的问题一般都用插空法做(高中数学都要还给老师了 T T),所以最后的结果是C(n-m+1,m)再对一个素数取模,n、p比较大,用lucas定理即可

完整代码:

#include <iostream>#include <string.h>#include <stdio.h>using namespace std;typedef long long LL;LL n,m,pp;int cnt;LL quick_mod(LL a,LL b){    LL ans=1;    while(b)    {        if(b&1)        {            ans=ans*a%pp;        }        b>>=1;        a=a*a%pp;    }    return ans;}LL C(LL n, LL m){    if(m > n) return 0;    LL ans = 1;    LL a=1;LL b=1;    while(m)    {        a=(a*n)%pp;        b=(b*m)%pp;        m--;        n--;    }    return a*quick_mod(b,pp-2)%pp;}int Lucas(LL n, LL m){    if(m==0) return 1;    return C(n%pp, m%pp)*Lucas(n/pp, m/pp)%pp;}int main(){    while(scanf("%lld%lld%lld", &n, &m, &pp)!=-1)    {        LL ans;        printf("%lld\n",Lucas(n-m+1,m)%pp);    }    return 0;}


原创粉丝点击