组合数

Problem 2020 组合

Accept: 1216    Submit: 2914
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数。例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大!于是xiaobo希望你输出 C(n,m) mod p的值!

 Input

输入数据第一行是一个正整数T,表示数据组数 (T <= 100) 接下来是T组数据,每组数据有3个正整数 n, m, p (1 <= m <= n <= 10^9, m <= 10^4, m < p < 10^9, p是素数)

 Output

对于每组数据,输出一个正整数,表示C(n,m) mod p的结果。

 Sample Input

25 2 35 2 61

 Sample Output

110

 Source

FOJ有奖月赛-2011年04月(校赛热身赛)


这题是个求组合数的题,求C(n,m) mod p;可以直接使用lucas定理直接过;快速幂求个逆元;


#include <iostream>  
#include <cstdio>  
using namespace std;  
typedef long long LL;  
LL n,m,p;  
LL power(LL a,LL b){  
    LL ans=1,temp=a%p;  
    while(b){  
        if(b&1) ans=ans*temp%p;  
        temp=temp*temp%p;  
        b>>=1;  
    }  
    return ans;  
}  
LL cal(LL a,LL b){ // Cm(a,b)=(a!/(a-b)!) * (b!)^(p-2)) mod p  
    if(b>a) return 0; // important  
    LL ans=1;  
    for(int i=1;i<=b;i++){  
        LL t1=(a-b+i)%p,t2=i%p;  
        ans=ans*(t1*power(t2,p-2)%p)%p;  
    }  
    return ans;  
}  
/*Lucas(n,m,p)=Cm(n%p,m%p)* Lucas(n/p,m/p,p) 
Lucas(x,0,p)=1;*/  
LL lucas(LL t1,LL t2){  
    if(t2==0) return 1;  
    return cal(t1%p,t2%p)*lucas(t1/p,t2/p)%p;  
}  
int main()  
{  
    //freopen("cin.txt","r",stdin);  
    int t;  
    cin>>t;  
    while(t--){  
        scanf("%lld%lld%lld",&n,&m,&p);  
        printf("%lld\n",lucas(n,m));  
    }  
    return 0;  
}  
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

じ☆夏妮国婷☆じ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值